1

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.

3
  • Are you talking a recursive or flat data structure? You use terms that make the distinction confusing. Commented Nov 24, 2010 at 8:25
  • 1
    It already is limited to C and its children. Commented Nov 24, 2010 at 8:26
  • your code should work. Can you show some more code fragment that don't? Commented Nov 24, 2010 at 8:30

4 Answers 4

2

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...

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, exactly. I have to do it just once but that's bad design, you are right.
2

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();
    }
}

Comments

1

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.

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.