当派生类的基类具有成员指针时,对其进行深层复制
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);
}
};
相关文章:
- 复制构造函数C++无法正确复制指针
- 如何在C++中复制指针数组的数据
- 如何编写复制构造函数来复制指针?
- 是否可以在不显式迭代每个元素的情况下深度复制指针容器?
- 复制指针,在不更改原始指针的情况下更改副本指向的内容?
- C++如何正确复制指针的容器(向量)
- 复制指针,然后调用 delete
- 是否应始终为具有原始指针成员的类中的深层复制指针定义复制构造函数
- C++复制指针
- 复制指针向量而不切片
- 如何以及何时复制指针
- 删除指向不同指针类型的复制指针是否会导致内存泄漏
- 复制指针值c++
- c++深度复制指针到带有指针值的映射
- 复制指针数组中动态创建的指针
- 如何复制指针到不完整类型- c++
- 复制指针类
- 模板中的内存分配指针和复制指针
- 写时复制指针对象
- 如何处理复制指针的释放