ขออภัยสำหรับซอร์สโค้ดจำนวนมากขึ้น มีคลาสนามธรรมสามคลาส P, L, PL PL คลาสที่สามได้มาจากคลาส P และ L โดยใช้การสืบทอดเสมือน:
template <typename T> //Abstract class
class P
{
public:
virtual ~P() = 0;
virtual P <T> *clone() const = 0;
};
template <typename T>
P<T>::~P() {}
template <typename T>
P<T> * P <T>:: clone() const { return new P <T> ( *this ); }
template <typename T> //Abstract class
class L
{
public:
virtual ~L() = 0;
virtual L <T> *clone() const = 0;
};
template <typename T>
L<T>::~L() {}
template <typename T>
L<T> *L <T> ::clone() const { return new L <T> ( *this );}
template <typename T>
class PL: virtual public P <T>, virtual public L <T> //Abstract class
{
public:
PL() : P <T>(), L<T>() {}
virtual ~PL() = 0;
virtual PL <T> *clone() const = 0;
};
template <typename T>
PL<T>::~PL() {}
template <typename T>
PL<T> * PL <T> :: clone() const { return new PL <T> ( *this );}
ทุกคลาสมีการนำเมธอดโคลนไปใช้เป็นของตัวเอง
PA, PC สองคลาสถัดไปได้มาจากคลาส P โดยใช้การสืบทอดเสมือน:
template <typename T>
class PC : virtual public P <T>
{
public:
PC() : P <T> () {}
virtual ~PC() {}
virtual PC <T> *clone() const {return new PC <T> ( *this );}
};
template <typename T>
class PA : virtual public P <T>
{
public:
PA() : P <T> () {}
virtual ~PA() {}
virtual PA <T> *clone() const {return new PA <T> ( *this );}
};
สองคลาสสุดท้าย PCL และ PAL ได้รับการสืบทอดโดยใช้การสืบทอดเสมือนจาก PC และ PL , PA และ PL
template <typename T>
class PCL : public PC <T>, public PL <T>
{
public:
PCL() : P <T> (), PC <T> (), PL <T> () {}
virtual ~PCL() {}
virtual PCL <T> *clone() const {return new PCL <T> ( *this );}
};
template <typename T>
class PAL : public PA <T>, public PL <T>
{
public:
PAL() : P <T> (), PA <T> (), PL <T> () {}
virtual ~PAL() {}
virtual PAL <T> *clone() const {return new PAL <T> ( *this );}
};
มีไดอะแกรมของการขึ้นต่อกันของคลาส:
.......... P .... L.....
........../|\..../......
........./.|.\../.......
......../..|..\/........
.......PC..PA..PL.......
.......|...|.../|.......
.......|...|../.|.......
.......|...PAL..|.......
.......|........|.......
.......PCL_____/........
กรุณาอย่าหารือเกี่ยวกับข้อเสนอนี้ :-))) ฉันมีคำถาม 3 ข้อต่อไปนี้:
1) การพึ่งพาคลาสนี้เขียนใหม่ในภาษา C ++ อย่างถูกต้อง (ก่อนอื่นคือการวางตำแหน่ง "เสมือน") หรือไม่
2) ฉันไม่แน่ใจว่ามีอะไรผิดปกติ ดูรหัส โปรด:
int main(int argc, _TCHAR* argv[])
{
PCL <double> * pcl = new PCL <double>(); //Object of abstract class not allowed
PAL <double> * pal = new PAL <double>(); //Object of abstract class not allowed
PL <double> *pl1 = pcl->clone(); //Polymorphism
PL <double> *pl2 = pal->clone(); //Polymorphism
return 0;
}
ไม่สามารถสร้างวัตถุใหม่ของคลาส PAL / PCL ได้ ทั้งสองคลาสจะถูกทำเครื่องหมายว่าเป็นนามธรรม แต่พวกมันไม่ใช่นามธรรม ปัญหาอยู่ที่ไหน?
3) เป็นไปได้ไหมที่จะใช้ polymorphism ร่วมกับวิธี clone() ดูรหัสด้านบนกรุณา...
ขอบคุณสำหรับความช่วยเหลือของคุณ...
คำถามที่อัปเดต
ฉันแก้ไขรหัสแล้ว แต่ข้อผิดพลาดต่อไปนี้ที่ใช้คอมไพเลอร์ VS 2010 ปรากฏขึ้น:
template <typename T> //Abstract class
class P
{
public:
virtual ~P() = 0;
virtual P <T> *clone() const = 0;
};
template <typename T>
P<T>::~P() {}
template <typename T>
P<T> * P <T>:: clone() const { return new P <T> ( *this ); }
template <typename T> //Abstract class
class L
{
public:
virtual ~L() = 0;
virtual L <T> *clone() const = 0;
};
template <typename T>
L<T>::~L() {}
template <typename T>
L<T> *L <T> ::clone() const { return new L <T> ( *this );}
template <typename T>
class PL: virtual public P <T>, virtual public L <T> //Abstract class
{
public:
PL() : P <T>(), L<T>() {}
virtual ~PL() = 0;
virtual PL <T> *clone() const = 0;
};
template <typename T>
PL<T>::~PL() {}
template <typename T>
PL<T> * PL <T> :: clone() const { return new PL <T> ( *this );}
template <typename T>
class PC : virtual public P <T>
{
protected:
T pc;
public:
PC() : P <T> () {}
virtual ~PC() {}
virtual PC <T> *clone() const {return new PC <T> ( *this );}
};
template <typename T>
class PA : virtual public P <T>
{
public:
PA() : P <T> () {}
virtual ~PA() {}
virtual PA <T> *clone() const {return new PA <T> ( *this );}
};
template <typename T>
class PCL : public PC <T>, public PL <T>
{
public:
PCL() : P <T> (), PC <T> (), PL <T> () {}
virtual ~PCL() {}
virtual PCL <T> *clone() const {return new PCL <T> ( *this );}
}; //Error using VS 2010: Error 1 error C2250: 'PCL<T>' : ambiguous inheritance of 'PC<T> *P<T>::clone(void) const'
template <typename T>
class PAL : public PA <T>, public PL <T>
{
public:
PAL() : P <T> (), PA <T> (), PL <T> () {}
virtual ~PAL() {}
virtual PAL <T> *clone() const {return new PAL <T> ( *this );}
}; //Error VS 2010: Error 1 error C2250: 'PAL<T>' : ambiguous inheritance of 'PA<T> *P<T>::clone(void) const'
int main(int argc, char* argv[])
{
PCL <double> * pcl = new PCL <double>();
PAL <double> * pal = new PAL <double>();
PL <double> *pl1 = pcl->clone();
PL <double> *pl2 = pal->clone();
return 0;
}
บางทีฉันอาจมองข้ามบางสิ่งบางอย่างไป ... แต่ g++ คอมไพล์โค้ดนี้ก็โอเค
P
,L
และPL
มีการใช้งานเริ่มต้นหรือไม่ - person Chad   schedule 03.08.2011= 0;
นอกจากนี้ ยังมีวงเล็บหายไปหลังจากPL <T> { }
(ควรเป็นPL <T>() { }
) ดังที่ @Chad กล่าวไว้ คุณไม่จำเป็นต้องสร้าง destructors เสมือนบริสุทธิ์ หากคุณมีฟังก์ชันเสมือนอื่น ๆ อยู่แล้ว - person Kerrek SB   schedule 03.08.2011