I have been plunging my brains trying to figure this out all day today...Its 2 am now. Please, someone explain the following to me: I know the virtual clone method is there in each class to facilitate the use of virtual copy constructors since you cannot directly declare
*virtual Mammal (const Mammal & rhs);* in this manner. However, I cannot understand what the clone method is doing. Lets say for example, at the prompt, I enter 2. Then the switch statement creates a Cat object on the free store and assigns it to ptr. Then ptr is assigned to theArray[i]. This cycle continues until the for loop ends. Then it executes the next for loop with the addresses stored in theArray[i] accessing the speak method. you see "Meow" in the output. In the next step it access the clone method and the both the Cat copy constructor and the Dog copy constructor is called. How is this possible? And what are the steps taking place here? How does the Cat's clone method call the copy constructors? It is possible that I am not understanding the fundamentals of *this as I suspect that this is responsible for calling the copy constructor.
*virtual Mammal (const Mammal & rhs);* in this manner. However, I cannot understand what the clone method is doing. Lets say for example, at the prompt, I enter 2. Then the switch statement creates a Cat object on the free store and assigns it to ptr. Then ptr is assigned to theArray[i]. This cycle continues until the for loop ends. Then it executes the next for loop with the addresses stored in theArray[i] accessing the speak method. you see "Meow" in the output. In the next step it access the clone method and the both the Cat copy constructor and the Dog copy constructor is called. How is this possible? And what are the steps taking place here? How does the Cat's clone method call the copy constructors? It is possible that I am not understanding the fundamentals of *this as I suspect that this is responsible for calling the copy constructor.
Code:
#include <iostream> using namespace std; class Mammal { public: Mammal():itsAge(1) { cout << "Mammal constructor...\n"; } ~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; }; //copy constructor defined Mammal::Mammal (const Mammal & rhs):itsAge(rhs.GetAge()) { cout << "Mammal Copy Constructor...\n"; } class Dog : public Mammal { public: Dog() { cout << "Dog constructor...\n"; } ~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 & rhs); 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 << "(0)Mammal (1)dog (2)cat: "; 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(); system("pause"); return 0; }
Comment