[英]C++: Deep copying a Base class pointer
我四处搜索,似乎为了执行此操作,我需要更改我的 Base 类,并想知道这是否是最佳方法。 例如,我有一个基类:
class Base {}
然后是一长串派生类:
class Derived_1:: public Base {}
class Derived_2:: public Derived_1{}
...
...
class Derived_n:: public Derived_M{}
然后我还有另一堂课:
class DeepCopy
{
Base * basePtr;
public:
DeepCopy(DeepCopy & dc) {}
}
假设 Base 类和 Derived_x 类复制构造函数被正确编码,那么为 DeepCopy 编写复制构造函数的最佳方法是什么。 我们如何知道我们要复制的对象的 basePtr 中的类?
我能想到的唯一方法是使用 RTTI,但使用一长串 dynamic_casts 似乎不对。 此外,它需要 DeepCopy 了解 Base 类的继承层次结构。
我看到的另一种方法是here 。 但它需要 Base 和 Derived 类实现克隆方法。
那么有没有更简单的标准方法来做到这一点?
您需要使用虚拟复制模式:在执行复制的接口中提供一个虚拟函数,然后跨层次结构实现它:
struct base {
virtual ~base() {} // Remember to provide a virtual destructor
virtual base* clone() const = 0;
};
struct derived : base {
virtual derived* clone() const {
return new derived(*this);
}
};
然后DeepCopy
对象只需要调用该函数:
class DeepCopy
{
Base * basePtr;
public:
DeepCopy(DeepCopy const & dc) // This should be `const`
: basePtr( dc.basePtr->clone() )
{}
};
使用采用clone()
函数的方法是一个很好的解决方案。 注意使用CRTP(奇怪的重复模板模式)可以为您节省一些工作。 你这样做的方法是引入一个中间级别(下面称为BaseCRTP
),它是一个模板并实现了clone()
函数。 当您派生实际类时,将它们用作它们派生自的基类的模板参数。 他们将自动为他们实现clone()
函数。 确保派生类实现了复制构造函数(或确保默认值是您需要的)。
/* Base class includes pure virtual clone function */
class Base {
public:
virtual ~Base() {}
virtual Base *clone() const = 0;
};
/* Intermediate class that implements CRTP. Use this
* as a base class for any derived class that you want
* to have a clone function.
*/
template <typename Derived>
class BaseCRTP : public Base {
public:
virtual Base *clone() const {
return new Derived(static_cast<Derived const&>(*this));
}
};
/* Derive further classes. Each of them must
* implement a correct copy constructor, because
* that is used by the clone() function automatically.
*/
class Derived1 : public BaseCRTP<Derived1> {
/*... should have an ordinary copy constructor... */
};
class Derived2 : public BaseCRTP<Derived2> {
/*... should have an ordinary copy constructor... */
};
然后,您显然可以以通常的方式实现DeepCopy
类:
class DeepCopy
{
Base *basePtr;
public:
DeepCopy(const DeepCopy &dc)
: basePtr(dc.basePtr->clone())
{}
};
我认为在这种情况下模板是最好的方法:
template<typename Sub>
class DeepCopy
{
Base *base;
DeepCopy(Sub *sub)
{
base = new Sub(*sub); // use copy constructor
}
}
这确实意味着DeepCopy
不可相互分配,但这是您使用 C++ 付出的代价。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.