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