簡體   English   中英

C++:深度復制基類指針

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM