[英]c++ pointers to base class has not got derived class member functions but pointer is created with derived
[英]Deep-copying a derived class when its base class has member pointers
我正在嘗試制作類Derived
的對象d
的深層副本,如下面的代碼所示:
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
正如您所看到的,只是在Derived的clone()
方法中返回new Derived(*this)
是錯誤的,因為它不會深層復制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
成員?
任何其他方法來解決這個問題?
您可以考慮實現始終執行深層復制的復制構造函數。 在這種情況下,您的clone
實現將始終是微不足道的:
class Base {
public:
A* m_a;
Base(const A& other)
: m_a(other.m_a->clone())
{
}
virtual Base* clone() {
return new A(*this);
}
};
class Derived : public Base {
public:
double m_dbl;
Derived(const Derived& other)
: m_dbl(other.m_dbl)
virtual Derived* clone() {
return new Derived(*this);
}
};
如果您不想更改默認構造函數的行為(例如,您希望默認構造函數進行淺層復制),則可以選擇將復制實現移動到CopyTo
方法,以便重用它:
class Base {
public:
A* m_a;
static void CopyTo(const Base& from, Base& to)
{
to.m_a = from.m_a->clone();
}
virtual Base* clone() {
Base* result = new Base();
CopyTo(*this, result);
return result;
}
};
class Derived : public Base {
public:
double m_dbl;
static void CopyTo(const Base& from, Base& to)
{
Base::CopyTo(from, to);
to.m_dbl= from.m_dbl;
}
virtual Derived * clone() {
Derived * result = new Derived ();
CopyTo(*this, result);
return result;
}
virtual Derived* clone() {
return new Derived(*this);
}
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.