2011-04-20 81 views
22

我一直在努力解決這類問題很長時間,所以我決定在這裏問一下。如何從指針複製/創建派生類實例到多態基類?

class Base { 
    virtual ~Base(); 
}; 
class Derived1 : public Base { ... }; 
class Derived2 : public Base { ... }; 
... 

// Copies the instance of derived class pointed by the *base pointer 
Base* CreateCopy(Base* base); 

的方法應返回動態創建的副本,或至少所述對象存儲在堆棧中的一些數據結構避免了「返回臨時的地址」的問題。

簡易方法來實現上述方法將使用多個typeid S或dynamic_cast S IN的一系列if語句,以檢查對於每個可能的派生類型,然後使用new運算符。 還有其他更好的方法嗎?

P.S .:我知道,這個問題可以通過使用智能指針來避免,但我對minimalistic方法感興趣,沒有一堆庫。

+1

這似乎是這個問題的確切副本:http://stackoverflow.com/questions/5148706/copying-a-polymorphic-object-in-c。請參閱Michael Anderson在那裏接受的答案。 – Darhuuk 2011-04-20 13:44:06

+1

@Darhuuk:我不太確定重複項目的SO政策是什麼,但這個問題有點不同。這裏的OP詢問解決這個問題的方法,而這個問題的OP詢問克隆是否是一種很好的C++方法。這顯然是相關的,只是不確定它是否是「完全重複」。 – ltjax 2011-04-20 14:02:37

+0

@Itjax夠公平的,只是給出的答案或多或少正是OP所期待的。雖然我猜你下面的答案更加方便:)。 – Darhuuk 2011-04-20 14:20:30

回答

34

您在您的基類中添加virtual Base* clone() const = 0;,並在您的派生類中適當地實現它。如果你的Base不是抽象的,你當然可以調用它的copy-constructor,但這有點危險:如果你忘記在派生類中實現它,你會得到(可能是不需要的)切片。

如果你不想重複的代碼,你可以使用CRTP idiom通過模板來實現功能:

template <class Derived> 
class DerivationHelper : public Base 
{ 
public: 
    virtual Base* clone() const 
    { 
    return new Derived(static_cast<const Derived&>(*this)); // call the copy ctor. 
    } 
}; 

class Derived1 : public DerivationHelper <Derived1> { ... }; 
class Derived2 : public DerivationHelper <Derived2> { ... }; 
+4

+1:這是規範的方法。 – 2011-04-20 13:40:47

1

另一種選擇是有共同的基礎純虛CreateCopy()方法在每個派生類中實現。

+0

你的意思是這樣的:http://ideone.com/FlQ9LF? – 2012-11-02 16:48:48

+0

@David Doria:Yeap,除了片段大量泄漏內存。 – sharptooth 2012-11-06 06:27:44

相關問題