我有3个类,2个继承自其他类:
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.
即。有时我想只迭代B对象,但有时我想迭代所有对象。
一种解决方案是将它们全部存储在列表中,但是我希望能够按类型顺序循环它们,即As然后是Bs然后是Cs。
另一个建议的解决方案是使用迭代器或iterator_adapters,但我以前从未使用它们,也找不到一个简单的例子来帮助我开始使用它们。
答案 0 :(得分:1)
boost iterator adapters可能会为您提供所需内容 - 您可以创建多态列表(所有项目),然后创建仅迭代B项或仅迭代C项的迭代器适配器。您可以使用标准迭代器列出所有项目。
正如其他人提到的,你需要多态列表来包含指针,这样你的项目就不会被切片。然后,您需要管理项目的生命周期,即确保在删除容器时删除它们。有一些智能指针类可以使这项任务更容易。
答案 1 :(得分:0)
如果你想拥有一个列表,你可以以多态方式迭代,以foo()
为所有对象进行迭代(也就是说,为每个对象调用正确的foo()
版本),你必须创建一个指向存储在其他容器中的所有对象的指针列表,并使用这些指针调用foo()。指针应该是A *。
我假设您的对象的所有权属于其他容器。
答案 2 :(得分:0)
我同意你的观点,即拥有一个列表会更容易维护这些对象。关键是你需要一种方法来了解列表中对象的动态类型,除非你想将所有子类(如B,C)函数添加到超类(如A)作为空虚函数。
如果你使用boost :: filter_iterator(boost中的一个专用适配器)并不重要,因为你仍然需要实现一个谓词函数来决定你是否正在寻找这个对象。
您可能想看看这个:Finding the type of an object in C++ 我会说它要么使用RTTI,要么在你的班级中添加自己的类型信息。