Я пытаюсь сделать глубокую копию объекта d
класса Derived
, как показано в коде ниже:
class A {
public:
int m_int;
A* clone() {
return new A(*this);
}
};
class Base {
public:
A* m_a;
virtual Base* clone() {
A* new_a = new A();
new_a = this->m_a->clone();
Base* clone = new Base(*this);
clone->m_a = new_a;
return clone;
}
};
class Derived : public Base {
public:
double m_dbl;
virtual Derived* clone() {
return new Derived(*this);
}
};
int main() {
Derived* d = new Derived();
d->m_dbl = 1.234;
A* a = new A();
a->m_int = -1;
d->m_a = a;
//clone d
Derived d_copy = d->clone();
//changing values of d's attributes must not affect d_copy
a->m_int = 10;
d->m_dbl = 3.456;
//check d_copy
cout << "m_int " << d_copy->m_a->m_int << endl;
cout << "m_dbl " << d_copy->m_dbl << endl;
}
выход:
m_int 10 //wrong, should be -1;
m_dbl 1.234 //correct
Как видите, просто возвращать new Derived(*this)
в методе Derived clone()
неверно, поскольку он не копирует глубоко m_a
.
Если я "сбью" глубокое копирование m_a
с Base
до Derived
, тогда я получу правильный ответ:
virtual Base* clone() = 0;
...
virtual Derived* clone() {
A* new_a = new A();
new_a = this->m_a->clone();
Derived* clone = new Derived(*this);
clone->m_a = new_a;
return new Derived(*this);
}
//gives out m_int = -1
Если это так, значит ли это, что каждый раз, когда я создаю дополнительные производные классы из Derived
, мне всегда приходится «сбрасывать» содержимое clone()
на них?
Кроме того, если, например, Base
имеет два производных класса Derived1
и Derived2
, означает ли это, что я должен глубоко копировать элементы Base
в каждом из них?
Есть ли другие способы подойти к этому?