Problem with std::vector
Good day people, I'm stuck with a silly C++ problem.
开发者_高级运维Let's say I have an iterator called it1 that goes through the values of a vector containing pointers to a class, we'll call it C:
std::vector<C*>::iterator it1;
But C is not alone: it has many subclasses, which share the same attributes and methods I'm looking for with it1, although their implementations may or may not differ. What should I do if I wanted the iterator to iter though elements (or better, pointers) not only of class C, but also of its children?
What I thought was something using templates, although that would make the iterations unsafe since I don't know how to limit the template only to C and its subclasses. Any suggestions?
Edit: yes, I was talking about a recursive data structure.
Edit2: Well, it seems like it wasn't the iterator's fault after all. My code worked fine, I asked the question because I was going to implement changes to it and I was unsure about what to do. Sorry if that was unclear.
I think I know what you mean. C is your base class and, say A and B derive from C. But there are functions is A and/or B which aren't there in C, is that what you mean? In this case I you'll have to downcast *it
to A*
or B*
. If this should be done in exceptional cases then OK, otherwise you should redesign...
This works fine:
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();
}
}
A vector<C*>::iterator will only work with a vector<C*>. Someone can make other iterators, but they won't work with your structure. And based on polymorphism, a vector<C*>::iterator can "point" to any subclass of C.
So long as you're only calling (virtual) methods defined in the public interface of class C, then inheritance and dynamic binding will take care of everything for you. So if you have, for example
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();
}
}
The iterator accesses each pointer, then calls the doit() function on each object accessed through the pointer - but dynamic binding comes into play to decide what version of the doit() function gets called depending on the run-time type of the object.
精彩评论