c++ แยกความแตกต่างระหว่างคลาสพื้นฐานในคลาสที่ได้รับอย่างไร

ฉันเข้าใจว่านี่ไม่ใช่ชื่อที่ดีที่สุด แต่ฉันไม่แน่ใจว่าจะอธิบายปัญหานี้ได้อย่างไรโดยไม่มีตัวอย่าง

ฉันมีคลาสพื้นฐาน (เรียกว่า vector3)

class vector3 {

    protected:
        double x,y,z;
public:
    vector3(): x(0),y(0),z(0) {}
    vector3(double xin, double yin, double zin): x(xin),y(yin),z(zin) {}
    ~vector3() {}

 //...other stuff

};

จากนั้นฉันก็มีคลาสอื่นที่ได้มาจาก vector3 เรียกว่า vector4:

class vector4 : public vector3 {

protected:
    double ct;
public:

    vector4(): vector3(0,0,0), ct=0 {}

    vector4(double ctin): ct(ctin) {}

    vector4(double ctin, double xin, double yin, double zin):
        vector3(xin, yin, zin), ct(ctin) {}

    vector4(double ctin, vector3 v):
        vector3(v.getx(), v.gety(), v.getz()), ct(ctin) {}

    ~vector4() {}

//...more other stuff

};

ไม่เป็นไร แต่ตอนนี้ฉันมีคลาสชื่อ particle กำหนดไว้ดังนี้:

class particle : public vector4 {
    protected:
        //vector4 r;
        double mass;
        //vector3 beta;
    public:
        particle(): vector4(0,0,0,0), mass=0, vector3(0,0,0) {}

        particle(vector4 rin, double massin, vector3 betain):
            vector4(rin.getx(),rin.gety(),rin.getz(),rin.getct()),
            mass=0,
            vector3(betain.getx(),betain.gety(),betain.getz()) {}

        ~particle() {}
        //...Further stuff
    };

ตอนนี้คำถามคือ:
ฉันจะส่งคืนค่า x, ค่า y และค่า z ของตำแหน่งของอนุภาค และค่า x, ค่า y และค่า z ของเวกเตอร์เบต้าของอนุภาคภายในฟังก์ชันในคลาสอนุภาคได้อย่างไร

ด้วยเวกเตอร์ 4 ฉันแค่ทำ:

double getx() const {
    return x;
}
double gety() const {
    return y;
}

ฯลฯ แต่ฉันจะใช้อะไรในคลาสของอนุภาค?


person Jamie Twells    schedule 21.03.2014    source แหล่งที่มา
comment
ฉันเชื่อว่าการใช้มรดกในกรณีนี้เป็นความคิดที่ดี อนุภาค เป็นเวกเตอร์จริงหรือ? หรือมันมีตำแหน่ง a?   -  person Shoe    schedule 21.03.2014
comment
ตรงเป๊ะเลย เวกเตอร์4 ไม่ใช่เวกเตอร์3 และอนุภาคไม่ใช่เวกเตอร์ โมเดลการสืบทอดคือความสัมพันธ์ และนั่นไม่ใช่สิ่งที่คุณมีอย่างชัดเจน ดังนั้นคุณจึงใช้คุณลักษณะภาษาที่ไม่ถูกต้องสำหรับสิ่งที่คุณต้องการทำ ชอบองค์ประกอบมากกว่ามรดก   -  person Asik    schedule 21.03.2014
comment
โดยปกติแล้ว คุณจะมีตำแหน่งเวกเตอร์ส่วนประกอบและความเร็วเวกเตอร์อีกค่าหนึ่งสำหรับแต่ละอนุภาค หรืออะไรสักอย่างในเส้นเหล่านั้น   -  person dutt    schedule 21.03.2014
comment
เคล็ดลับจากมืออาชีพ: คอมไพลเลอร์จะสร้างตัวทำลายล้างที่ว่างเปล่าให้คุณโดยอัตโนมัติโดยที่คุณไม่ต้องทำอะไรเลย อย่าไปยุ่งกับเรื่องอย่าง ~vector3() {}   -  person R. Martinho Fernandes    schedule 21.03.2014
comment
@R.MartinhoFernandes แต่ฉันเสียคะแนนถ้าไม่ทำ... :)   -  person Jamie Twells    schedule 21.03.2014
comment
@captainjamie คุณอาจเพิ่มความคิดเห็นบอกครูว่าคอมไพเลอร์ที่สร้าง destructor ทำในสิ่งที่จำเป็นต้องทำอย่างแน่นอน เขา (หวังว่า) แค่อยากรู้ว่าคุณไม่ลืม destructors เมื่อเขียนชั้นเรียน   -  person Arne Mertz    schedule 21.03.2014


คำตอบ (2)


เวกเตอร์ตำแหน่งและเบต้าเป็นคุณลักษณะของอนุภาค ดังนั้นคุณควรใช้การรวมแทนการสืบทอด:

class particle {
    protected:
        vector4 r;
        double mass;
        vector3 beta;
    // ...

คุณควรใช้การสืบทอดเฉพาะในกรณีที่มีความสัมพันธ์ is-a ระหว่างคลาสย่อยและซูเปอร์คลาส

person ecatmur    schedule 21.03.2014
comment
ใช่ โอเค นั่นดูเหมือนเป็นวิธีที่สมเหตุสมผลมากกว่าใช่ไหม ฉันจะให้เวลาผู้อื่นสักสองสามนาทีเพื่อขอคำแนะนำก่อนที่จะทำเครื่องหมายคำตอบที่ยอมรับ - person Jamie Twells; 21.03.2014

ในกรณีของคุณ อนุภาคคือ vector4 ดังนั้นคุณจึงสามารถกำหนด getters สาธารณะใน vector4 และเรียก particle.getX() โดยตรง

อย่างไรก็ตาม ดูเหมือนว่านี่จะไม่ใช่ความคิดที่ดี ในความคิดของฉัน อนุภาคควรมีเวกเตอร์ เนื่องจากไม่ใช่ความเชี่ยวชาญเฉพาะทางของคลาส vector4

สมมติว่าอนุภาคมีเวกเตอร์ชื่อ _vector

คุณสามารถกำหนดวิธีการดังนี้:

double getX(void) const
{
  return (_vector.getX());
}

เหมือนกันสำหรับ getY

person Intrepidd    schedule 21.03.2014
comment
โอเค สมมติว่า beta นั้นเป็น vector4 เหมือนกัน ฉันจะคืนมันได้อย่างไร - person Jamie Twells; 21.03.2014