2010-05-22 102 views
2

我有3個班,2個來自其他繼承像這樣:遍歷多個列表連續(C++)

class A { 
    public: 
    virtual void foo() {cout << "I am A!" << endl;} 
}; 

class B : public A { 
    public: 
    void foo() {cout << "B pretending to be A." << endl} 
    void onlyBFoo() {cout << "I am B!" << endl} 
}; 

class C : public A { 
    public: 
    void foo() {cout << "C pretending to be A." << endl} 
    void onlyCFoo() {cout << "I am C!" << endl} 
}; 

我想要做的是這樣的:

list<A*> list_of_A; 
list<B*> list_of_B; 
list<C*> list_of_C; 

//put three of each class in their respective list 

cout << "First loop:" << endl; 
for (list<B>::iterator it = list_of_B.begin(); it != list_of_B.end(); ++it) { 
    (*it)->onlyBFoo(); 
} 

cout << "Second loop:" << endl; 
for (list<C>::iterator it = list_of_C.begin(); it != list_of_C.end(); ++it) { 
    (*it)->onlyCFoo(); 
} 

//This part I am not sure about 
cout << "Third loop:" << endl; 
for (Iterate all 3 loops i.e. *it points to As, then Bs then Cs) { 
    (*it)->foo(); 
} 

爲了輸出:

First loop: 
I am B! 
I am B! 
I am B! 

Second loop: 
I am C! 
I am C! 
I am C! 

Third loop: 
I am A! 
I am A! 
I am A! 
B pretending to be A. 
B pretending to be A. 
B pretending to be A. 
C pretending to be A. 
C pretending to be A. 
C pretending to be A. 

ie ie有時我只想迭代B對象,但有時我想迭代所有的對象。

一個解決辦法是將它們全部存儲在一個列表中,但是我希望能夠通過他們循環型即作爲BS然後再Cs的順序。

另一種建議的解決方案是使用迭代器或iterator_adapters,但我從來沒有使用過,並不能找到一個簡單的例子來幫我開始使用它們。

+0

你要遍歷的A'''B'和在一個循環'C'對象,每個對象上調用不同的功能列表。我理解正確嗎? – wilhelmtell 2010-05-23 00:05:30

+0

您是否知道'it-> foo()'等同於(並優先於)'(* it).foo()'? – 2010-05-23 02:37:39

+0

@wilhelm - 不完全 - 有時我想循環遍歷所有的B和僅調用B的函數,有時我想遍歷所有的As及其子類,並調用從A繼承/覆蓋的函數,即單獨的循環。 我已經重寫了這個問題,以便更清楚我想要什麼。 – 2010-05-24 15:16:40

回答

0

如果你想有一個列表,你可以遍歷,調用foo(),在一個多態的方式的所有對象(也就是這樣的foo()正確版本被調用爲每個對象),你必須創建一個指向所有存儲在其他容器中的對象的指針列表,並使用這些指針調用foo()。指針應該是A *類型的。

我假設你的對象的所有權屬於那些其他容器。

1

提升iterator adapters可能會給你你需要的東西 - 你可以創建一個多態列表(所有的項目),然後創建迭代器適配器只遍歷B項或者只有C項。您可以使用標準迭代器來列出所有項目。

正如其他人所說,你需要多態列表中包含指針,讓你的項目沒有得到切片。然後您需要管理項目的生命週期,即確保在刪除容器時刪除它們。有智能指針類可以使這個任務更容易。

+0

這聽起來像我想要的,但是我之前沒有使用迭代器,它看起來很複雜。有什麼簡單的例子可以告訴我嗎? – 2010-05-24 15:23:33

0

我同意你的想法,即擁有單個列表將更容易維護這些對象。關鍵是你需要一種方法來知道列表中的對象的動態類型,除非你想把所有的子類(比如B,C)添加到你的超類(比如A)中作爲空虛擬函數。

不要緊,無論你使用(在提升一個專門的適配器)的boost :: filter_iterator因爲你仍然需要執行一個斷言函數來決定,如果這個對象是你在找什麼。

你可能想看看這個:Finding the type of an object in C++ 我會說它要麼使用RTTI,要麼將自己的類型信息添加到你的類中。