美好的一天, 我遇到了一个愚蠢的C ++问题。
假设我有一个名为it1的迭代器,它遍历包含指向类的指针的向量值,我们称之为C:
std::vector<C*>::iterator it1;
但是C并不孤单:它有许多子类,它们与it1共享相同的属性和方法,尽管它们的实现可能会有所不同。如果我希望迭代器通过不仅是C类的元素(或更好的指针)而且还需要它的子代,我该怎么办?
我认为使用模板的东西,虽然这会使迭代不安全,因为我不知道如何仅将模板限制为C及其子类。有什么建议吗?
编辑:是的,我在谈论递归数据结构。
Edit2:好吧,看起来好像不是迭代者的错。我的代码运行正常,我问了这个问题,因为我要对它进行更改,我不确定该怎么做。对不起,如果不清楚的话。
答案 0 :(得分:2)
这很好用:
class C
{
public:
virtual void WhoAmI() { std::cout << "C\n"; }
};
class D: public C
{
public:
virtual void WhoAmI() { std::cout << "D\n"; }
};
int main()
{
C cObject;
D dObject;
std::vector<C*> data;
data.push_back(&cObject);
data.push_back(&dObject);
std::vector<C*>::iterator it1;
for(it1 = data.begin(); it1 != data.end(); ++it1)
{
(*it1)->WhoAmI();
}
}
答案 1 :(得分:2)
我想我知道你的意思。 C是你的基类,比如说A和B来自C。但是有些函数是A和/或B,它们不在C中,是你的意思吗?在这种情况下,我必须将*it
转发给A*
或B*
。如果这应该在特殊情况下完成,那么好的,否则你应该重新设计......
答案 2 :(得分:1)
向量&lt; C *&gt; :: iterator仅适用于向量&lt; C *&gt;。有人可以制作其他迭代器,但它们不适用于您的结构。并且基于多态性,向量&lt; C *&gt; :: iterator可以“指向”C的任何子类。
答案 3 :(得分:1)
只要您只调用C类公共接口中定义的(虚拟)方法,继承和动态绑定就会为您处理所有事情。所以,如果你有,例如</ p>
class C {
public:
virtual oid doit() { std::cout << "I am a C object" << std::endl; }
};
class D : public C {
public:
void doit() { std::cout << "I am a D object" << std::endl; }
};
int main()
{
C c;
D d;
std::vector<C*> cs;
cs.push_back(&c);
cs.push_back(&d);
vector<C*>::iterator ci;
for (ci = cs.begin(); ci != cs.end(); ci++) {
(*ci)->doit();
}
}
迭代器访问每个指针,然后在通过指针访问的每个对象上调用doit()函数 - 但是动态绑定起作用以决定调用doit()函数的哪个版本,具体取决于运行时类型对象。