构造函数不能是虚函数。但有时候确实需要能传递一个指向基类对象的指针,并且有已创建的派生类对象的拷贝。通常在类内部创建一个Clone()方法,并设置为虚函数。



//Listing 12.11 Virtual copy constructor #include <iostream> using namespace std;  class Mammal {   public:      Mammal():itsAge(1) { cout << "Mammal constructor...\n"; }      virtual ~Mammal() { cout << "Mammal destructor...\n"; }      Mammal (const Mammal & rhs);      virtual void Speak() const { cout << "Mammal speak!\n"; }      virtual Mammal* Clone() { return new Mammal(*this); }      int GetAge()const { return itsAge; }   protected:      int itsAge; };  Mammal::Mammal (const Mammal & rhs):itsAge(rhs.GetAge()) {    cout << "Mammal Copy Constructor...\n"; }  class Dog : public Mammal {   public:     Dog() { cout << "Dog constructor...\n"; }     virtual ~Dog() { cout << "Dog destructor...\n"; }     Dog (const Dog & rhs);     void Speak()const { cout << "Woof!\n"; }     virtual Mammal* Clone() { return new Dog(*this); } // 这里! };  Dog::Dog(const Dog & rhs): Mammal(rhs) {    cout << "Dog copy constructor...\n"; }  class Cat : public Mammal {   public:     Cat() { cout << "Cat constructor...\n"; }     ~Cat() { cout << "Cat destructor...\n"; }     Cat (const Cat &);     void Speak()const { cout << "Meow!\n"; }     virtual Mammal* Clone() { return new Cat(*this); } };  Cat::Cat(const Cat & rhs): Mammal(rhs) {    cout << "Cat copy constructor...\n"; }  enum ANIMALS { MAMMAL, DOG, CAT}; const int NumAnimalTypes = 3; int main() {    Mammal *theArray[NumAnimalTypes];    Mammal* ptr;    int choice, i;    for ( i = 0; i<NumAnimalTypes; i++)    {       cout << "(1)dog (2)cat (3)Mammal: ";       cin >> choice;       switch (choice)       {         case DOG:   ptr = new Dog;                    break;         case CAT:   ptr = new Cat;                    break;         default:   ptr = new Mammal;                    break;       }       theArray[i] = ptr;    }    Mammal *OtherArray[NumAnimalTypes];    for (i=0;i<NumAnimalTypes;i++)    {       theArray[i]->Speak();       OtherArray[i] = theArray[i]->Clone();    }    for (i=0;i<NumAnimalTypes;i++)       OtherArray[i]->Speak();    return 0; }


输出结果:

(1)dog (2)cat (3)Mammal: 3

Mammal constructor...

Woof!

Mammal Copy Constructor...

Dog copy constructor...

Meow!

Mammal Copy Constructor...

Cat copy constructor...

Mammal speak!

Mammal Copy Constructor...

Woof!

Meow!

Mammal speak!