2011-02-02 74 views
1

我有一個抽象基類來執行一些子類來重載運算符。複製抽象基類的子類

我在std :: stack中存儲了一堆指向這些子類的實例的指針......在某些時候,我希望複製堆棧的頂層項目(並將其推到頂部)。

問題是,我無法實例化一個抽象類。很明顯,因爲我想爲我的每個子類做這件事,所以我不知道類型...

我不知道這是甚至可能沒有添加另一個純粹的虛擬方法(說'Base * clone()= 0')並在我的每個子類中實現它?當然必須有一個更清潔的方式。

回答

4

我想你在這種情況下實際上需要一個Clone方法。您希望在運行時動態複製子類項目,並且在運行時更改行爲的常規方法是虛擬方法。如果不使用某種虛擬方法,您將無法確定它是哪個孩子。你也許可以使用CRTP自動生成克隆你,但:

// Totally uncompiled and untested. 
class Base 
{ 
public: 
    virtual Base* Clone() const = 0; 
}; 

template <class T> 
class Child : public Base 
{ 
public: 
    virtual Base* Clone() const { return new T(*static_cast<T*>(this)); } 
protected: 
    Child(); // Can't instantiate directly 
    Child(const Child& right); // Can't instantiate directly 
}; 

class Grandchild : public Child<Grandchild> 
{ 
    // Clone should do the right thing. 
}; 
+0

完美!非常感謝。 – 2011-02-02 05:59:17

0

你的意思是使類的副本,而不是複製指針。

您將需要實現自己的輸入。換句話說有一個虛函數返回類的類型,然後創建合適的類

或者啓用RTTI(運行時類型信息)來做同樣的事情。因爲RTTI對每個類都有影響,因此可以更有效地創建自己的類型方法。

然後你就可以

  1. 流行指針
  2. 獲取型
  3. 實例化一個 開關使用 一個拷貝構造函數可能是正確的類
  4. 推兩回壓入堆棧

psuedocode

base* ptr = stack.pop() 
base *copy 
switch (ptr->typeof()) { 
    case class1type : copy = new class1(ptr) break; 
    case class2type : copy = new class2(ptr) break; 
    ... 
} 

stack.push (ptr) 
stack.push(copy) 

DC