C ++:深复制一个基类指针(C++: Deep copying a Base class poin

2019-06-27 18:07发布

我搜索周围,似乎为了执行这个我需要改变我的基类,想知道这是否是最好的办法。 例如,我有一个基类:

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) {}
}

假设基类和Derived_x类的拷贝构造函数被正确编码,什么是写deepcopy的拷贝构造函数的最佳方式。 我们怎样才能知道这是我们要复制对象的basePtr类?

只有我能想到的是使用RTTI,但使用dynamic_casts一长串的方式似乎不正确的。 除了它需要deepcopy的了解基类的继承层次。

我看到了另一种方法是在这里 。 但是,它需要基类和派生类实现一个克隆方法。

那么,有没有这样做的更加容易,标准的方式?

Answer 1:

您需要使用虚拟副本模式:提供,做拷贝,然后跨层次实现它的接口的虚拟函数:

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() )
   {}
};


Answer 2:

使用采用的方法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())
  {}
};


Answer 3:

我认为,模板是在这种情况下,以最好的一段路要走:

template<typename Sub>
class DeepCopy
{
    Base *base;

    DeepCopy(Sub *sub)
    {
        base = new Sub(*sub); // use copy constructor
    }
}

这是否意味着DeepCopy的是未分配给对方,不过这就是你使用C付出的代价++。



文章来源: C++: Deep copying a Base class pointer