#c #clone
#c #клонирование
Вопрос:
Я был на теме «конструктор виртуальной копии» в своей книге. В абзаце говорится
Конструкторы не могут быть виртуальными, и поэтому технически не существует такой вещи, как конструктор виртуальной копии. Тем не менее, иногда вашей программе отчаянно необходимо иметь возможность передавать указатель на базовый объект и иметь копию правильного созданного производного объекта. Общее решение этой проблемы — создать метод Clone() в базовом классе и сделать его виртуальным. Метод Clone() создает новую копию объекта текущего класса и возвращает этот объект.
И затем книга дала следующий код (я удалил некоторую его часть, которая не была необходимой, связанной с моими сомнениями).
#include <iostream>
using namespace std;
class Mammal
{
public:
Mammal() {}
Mammal (const Mammal amp; rhs);
virtual void Speak() const
{
cout << "Mammal speak!n";
}
virtual Mammal* Clone()
{
return new Mammal(*this);
}
};
Mammal::Mammal (const Mammal amp; rhs)
{
cout << "Mammal Copy Constructorn";
}
class Dog : public Mammal
{
public:
Dog() {}
Dog (const Dog amp; rhs);
void Speak()const
{
cout << "Woof!n";
}
virtual Mammal* Clone()
{
return new Dog(*this);
}
};
Dog::Dog(const Dog amp; rhs): Mammal(rhs)
{
cout << "Dog copy constructor...n";
}
enum ANIMALS { MAMMAL, DOG};
const int NumAnimalTypes = 2;
int main()
{
Mammal* theArray[NumAnimalTypes];
Mammal* ptr;
int choice, i;
for ( i = 0; i<NumAnimalTypes; i )
{
cout << "(1)dog (2)Mammal: ";
cin >> choice;
switch (choice)
{
case DOG: ptr = new Dog;
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)Mammal: 1
(1)dog (2)Mammal: 2
Woof!
Mammal Copy Constructor
Dog copy constructor...
Mammal speak!
Mammal Copy Constructor
Woof!
Mammal speak!
Я не получил точной интуиции, лежащей в основе использования clone()
метода. Это означает, что я закомментировал clone()
функциональную часть в приведенном выше коде и изменил шестую последнюю строку на OtherArray[i] = theArray[i];
, и я предполагаю, что это все еще делает то, что намеревался сделать фактический код.
Мой код:
#include <iostream>
using namespace std;
class Mammal
{
public:
Mammal() {}
Mammal (const Mammal amp; rhs);
virtual void Speak() const
{
cout << "Mammal speak!n";
}
/* virtual Mammal* Clone()
{
return new Mammal(*this);
} */
};
Mammal::Mammal (const Mammal amp; rhs)
{
cout << "Mammal Copy Constructorn";
}
class Dog : public Mammal
{
public:
Dog() {}
Dog (const Dog amp; rhs);
void Speak()const
{
cout << "Woof!n";
}
/* virtual Mammal* Clone()
{
return new Dog(*this);
} */
};
Dog::Dog(const Dog amp; rhs): Mammal(rhs)
{
cout << "Dog copy constructor...n";
}
enum ANIMALS { MAMMAL, DOG};
const int NumAnimalTypes = 2;
int main()
{
Mammal* theArray[NumAnimalTypes];
Mammal* ptr;
int choice, i;
for ( i = 0; i<NumAnimalTypes; i )
{
cout << "(1)dog (2)Mammal: ";
cin >> choice;
switch (choice)
{
case DOG: ptr = new Dog;
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];
}
for (i=0;i<NumAnimalTypes;i )
OtherArray[i]->Speak();
return 0;
}
Вывод:
(1)dog (2)Mammal: 1
(1)dog (2)Mammal: 2
Woof!
Mammal speak!
Woof!
Mammal speak!
Может кто-нибудь, пожалуйста, объясните мне, почему и где нам нужно использовать clone()
метод и его связь с конструктором виртуальной копии. Спасибо.
Комментарии:
1. Ваша измененная версия не копирует объекты, а только указывает на них.
2. Не оставляйте виртуальный деструктор (по другим причинам). Я также отмечаю, что у ваших объектов нет данных для копирования, поэтому они не подходят для использования в случае необходимости клонирования.
3. Суть примера не в звуках животных, а в копировании, и из выходных данных ясно, что ваша версия ничего не копирует.