2010-05-22 104 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,要么将自己的类型信息添加到你的类中。