ฟังก์ชั่นสมาชิกกับฟังก์ชั่นที่ไม่ใช่สมาชิกสำหรับผู้ประกอบการคณิตศาสตร์


12

ฉันกำลังเขียนห้องสมุดพีชคณิตเชิงเส้น (เรื่องสั้นสั้น ๆ มันเป็นโรงเรียนที่ได้รับมอบหมาย) ที่เกี่ยวข้องกับเมทริกซ์เวกเตอร์ ฯลฯ ในกระบวนการสร้างห้องสมุดนี้ฉันจะต้องสร้างฟังก์ชั่นที่ดำเนินการทางคณิตศาสตร์กับวัตถุ ตัวอย่างเช่น transpose matrix, invert matrix, normalize vector และอื่น ๆ

ฉันสงสัยว่า "วิธีปฏิบัติที่ดีที่สุด" สำหรับฟังก์ชั่นประเภทนี้คืออะไรนั่นคือฉันควรทำให้ฟังก์ชั่นเป็นฟังก์ชันสมาชิกหรือไม่เป็นสมาชิกหรือไม่? (เพื่อความชัดเจน / ใช้ประโยชน์สาเก)

ตัวอย่าง:

//Member function way:
B = A.transpose();
C = A.inverse();

//Non-member function way:
B = linalg::transpose(A); //Non-member transpose function in linear algebra namespace
C = linalg::inverse(A);

มีมาตรฐานเกี่ยวกับการดำเนินการหลายประเภทบ้างไหม? หรืออย่างน้อยก็มีวิธีธรรมดา ๆ ที่ผู้คนจะทำเช่นนี้? ฉันกำลังมุ่งไปที่ตัวเลือกแรก แต่ฉันอยากจะรู้ว่านี่เป็นสิ่งที่แนะนำหรือไม่

คำตอบ:


7

นี่เป็นเพียงเรื่องของสไตล์และรสนิยม ฉันได้เห็นห้องสมุดพีชคณิตเชิงเส้นที่แตกต่างกันเช่นกัน

  • เขียนในสไตล์ OOP โดยใช้ฟังก์ชั่นสมาชิก

  • เขียนในรูปแบบที่ไม่ใช่ OOP โดยใช้ฟังก์ชั่นฟรีเท่านั้น

  • ให้ API กับทั้งสอง

และพวกเขาทั้งหมดกำลังทำงาน อย่างน้อย API ของคุณควรสอดคล้องดังนั้นเลือกตัวเลือกของคุณและตรวจสอบให้แน่ใจว่าคุณไม่ได้ผสมสไตล์เหล่านั้นโดยพลการ


8

หลีกเลี่ยงค่าธรรมเนียมการเป็นสมาชิก: หากเป็นไปได้ควรทำฟังก์ชั่นที่ไม่ใช่สมาชิก nonfriends

ฟังก์ชั่นที่ไม่ใช่สมาชิกที่ไม่ได้เป็นสมาชิกปรับปรุงการห่อหุ้มโดยการลดการพึ่งพา: ย่อส่วนของฟังก์ชันไม่สามารถขึ้นอยู่กับสมาชิกที่ไม่ใช่สาธารณะของชั้นเรียน (ดูหัวข้อ 11) พวกมันยังแยกชั้นหินใหญ่ออกเป็นชั้น ๆ เพื่อปลดปล่อยการทำงานที่แยกกันได้ช่วยลดการมีเพศสัมพันธ์ (ดูข้อ 33) พวกเขาปรับปรุง genericity เพราะมันยากที่จะเขียนแม่แบบที่ไม่ทราบว่าการดำเนินการเป็นสมาชิกของประเภทที่กำหนด [... ]

สมุนไพรซัทเทอร์


1
ในที่สุดคำตอบที่ดี: สาย แต่ไม่สายเกินไป ;-) อีกอ้างอิง: GotW # 84: เสาหิน "Unstrung"
Deduplicator

1

ฟังก์ชั่นสมาชิกและไม่ใช่สมาชิกมีข้อดีจริงนอกเหนือจากรสชาติเพียง ตัวอย่างเช่นอาเรย์พื้นฐานที่ใช้ในการใช้matrixคลาสอาจจะเป็นprivateดังนั้นคุณจะต้องใช้friendเว้นแต่คุณจะใช้ฟังก์ชั่นสมาชิก ในแง่นี้การออกแบบ OO อาจดีกว่า

อย่างไรก็ตามโปรดจำไว้ว่านักวิทยาศาสตร์คอมพิวเตอร์ต้องใช้สูตรคณิตศาสตร์ที่ซับซ้อนเป็นครั้งคราวโดยที่ไม่รู้ว่าเจ้าทำอะไรจริงๆ เมื่อฉันต้องทำฉันฟังก์ชั่นที่ไม่ใช่สมาชิกล่วงหน้าเนื่องจากผลลัพธ์ "ภาพ" จะใกล้เคียงกับสูตรคณิตศาสตร์ดั้งเดิม (โดยทั่วไปสูตรคณิตศาสตร์จะใช้รูปแบบการทำงาน)

ในท้ายที่สุดคำตอบก็เหมือนกับของ Doc Brown นั่นคือเรื่องของรสนิยม ในระยะสั้นคุณสามารถพิจารณาการเขียนไลบรารีสไตล์ OO ด้วยฟังก์ชั่นสมาชิก (เขียนง่ายขึ้นไม่ใช่friend) จากนั้นเขียนฟังก์ชันที่ไม่ใช่สมาชิกเพื่อทำงานเดียวกันซึ่งจะส่งต่อข้อโต้แย้งไปยังสมาชิก ช่วยให้คุณมีความสอดคล้องและให้ผู้ใช้เลือกสิ่งที่เขาคิดว่าดีที่สุด


0

หากคุณดำน้ำลึกลงไปในคำแถลงปัญหาของคุณเป็นที่ชัดเจนว่าในบางจุดคุณจะใช้โครงสร้างข้อมูลแบบกำหนดเองที่แสดงถึงเอนทิตีทางคณิตศาสตร์บางอย่าง ตัวอย่างเช่นคุณอาจแสดงเมทริกซ์ค่าเฉลี่ยของฉันของอาร์เรย์ n-มิติ เพื่ออธิบายตัวอย่างของคุณอย่างละเอียด

// C way
typedef struct {
    int data[MAX_LEN][MAX_LEN];
} MATRIX;

MATRIX B = transpose(A);

// C++ way
class Matrix; // Forward Declaration
class Matrix {
    int data[MAX_LEN][MAX_LEN];
    public:
        Matrix transpose();
};

Matrix B = A.transpose();

(ตัวอย่าง C ++ นั้นง่ายขึ้นคุณสามารถใช้เทมเพลตและอื่น ๆ ได้)

จุดที่ต้องพิจารณาคือความง่ายในการใช้โครงสร้างข้อมูลแบบกำหนดเองในทั้งสองกรณี C ++ (หรือวัตถุใด ๆ ที่มุ่งเน้น) ในฐานะภาษานั้นมีประสิทธิภาพมากกว่าในตัวมันเองและมันขยายไปถึงกลุ่มผู้บริโภคของห้องสมุด ฉันเคยใช้ห้องสมุด C เท่านั้นในอดีตและโครงสร้างข้อมูลที่กำหนดเองเหล่านั้นดูเหมือนจะไปทั่วในเวลาไม่นาน! ในขณะที่การทำงานร่วมกันเป็นเรื่องง่ายกว่าที่จะบรรลุกับหลัง (ใช้ตัวสร้างพิเศษอาจ?)

หากต้องการใช้ C ++ คุณควรใช้วิธีการเชิงวัตถุ


5
ขออภัยมีเหตุผลที่ชัดเจนเล็กน้อยในการให้เหตุผลของคุณ ไม่มีความแตกต่างในความง่ายในการใช้งานระหว่างสองtransposeตัวอย่างของคุณ เหตุผลหลักที่ C ++ คือง่ายกว่านั้นก็เพราะการทำสำเนาและการกำหนดความหมายใช้งานได้จริง A = Bอาจรวบรวมใน C แต่อาจทำสิ่งที่ผิด
MSalters

+1 สำหรับซีแมนทิกส์สำเนาจุดที่ฉันพยายามข้ามคือการใช้วัตถุ (ห่อหุ้ม "การแทน") v / s โดยใช้ชุดโครงสร้างและฟังก์ชันที่เกี่ยวข้องกันอย่างหลวม ๆ
dotbugfix
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.