2011-10-31 211 views
2

我在Ubuntu 11.10和最新版本的NetBeans中使用C++。比方說,我有 下面的代碼:如何:派生類中派生類的派生類與特定於派生類的方法

class Node {} 
class DerivedNode : public Node {} 

class Graph { 
    vector<Node*> nodes; 
} 

class DerivedGraph : public Graph { } 

在我存儲DerivedNodes在DerivedGraph類像這樣的例子時刻:

nodes.push_back(new DerivedNode()); 

當我需要使用只適用於特定的方法DerivedNodes和DerivedGraphs 我不得不先在我的節點指針上使用dynamic_cast。

我希望能夠在DerivedGraph中具體應用DerivedNodes ,避免需要投射指針。如果結果 的結果比我的要好,我不介意重新設計我的課程。

我確定必須有一個乾淨而簡單的方法來實現我想要做的同樣的事情。 也許用專門的模板?任何關於此事的想法都會大大促進 。我還會提供所需的任何附加信息,但我並不清楚 。

編輯:我沒有兩個副本。我想強調它的外觀。我爲演示道歉。我想獲得的是:

class DerivedGraph: public Graph { 
    vector<DerivedNode*> nodes; 
}  
+2

爲什麼你有**兩個**節點的拷貝? –

+0

@Morat:再次檢查。 'DerivedGraph'具有一個'nodes'成員,並且它也繼承'Graph'的'nodes'成員。所以'DerivedGraph'有兩個'節點'成員。 –

+0

我明白你的意思。我會重新編輯我原來的問題,因爲它似乎會產生混淆。我的實際代碼沒有節點容器兩次。 – Morat

回答

1

你是肯定你的界面在Node是合適的嗎?有時,當你發現自己需要向下轉發(特別是在基本指針存儲在容器中的情況下),這可能表明你的抽象接口不能正確覆蓋所有需求。通常類似於模板方法模式可以解決您的所有需求,而不需要任何沮喪。

但是,假設您的繼承模型真的需要這樣工作,您可能想要做的是在DerivedGraph中添加和獲取節點的虛擬方法。在這種情況下,您需要驗證節點類型並向下轉發。

最後一個方法是有兩個分開的容器,一個在包含不DerivedNode然後在DerivedGraph另一個容器包含所有DerivedNode所有節點的父代。然後再次使用重寫函數來確定訪問哪個容器,具體取決於您的API需求。

+0

我認爲在這裏新來的人在描述我的問題時遇到了問題。下面的細節是否會以任何方式改變你的建議:我知道DerivedGraph必須並且只會包含DerivedNodes。我需要DerivedGraph具有普通圖形的所有功能以及一些額外的功能,但它只包含DerivedNodes。這就是爲什麼我認爲這可以通過專門的模板解決的原因。只是一個想法。 – Morat

1

首先在派生類中複製數據成員。

然後添加您用於將數據添加到容器的虛擬成員函數。這樣你就可以在派生類中創建派生類型的實例並將它們添加到容器中。

最後,當您覆蓋返回派生類中的數據引用的虛函數時,請使用covariant return types

+0

是的,但是當我在需要訪問DerivedNode的成員的DerivedGraph中有方法時,我仍然需要將節點指針轉換爲DerivedNode指針。任何方法來避免演員? – Morat

+0

您無法完全避免投射,但如果您的類的不變量保證投射始終成功,您可以使用'static_cast'來避免'dynamic_cast'的運行時成本。 –