vendredi 26 décembre 2014

Treating a collection of pointers to instances of a derived class as if they were the parent class

(This question has probably been answered before, and I can find similar questions, but nothing that I can apply to my situation. Links to relevant questions are of course appreciated.)


Here is an illustration of what I'm trying to do:



#include <vector>

class Abstract
{
public:
virtual std::vector<Abstract *> children() = 0;
};

class Concrete : public Abstract
{
public:
std::vector<Abstract *> children() override {return std::vector<Abstract *>();}
/* This returns an empty vector. What should actually go here, to return the actual children? */
private:
std::vector<Concrete *> m_children;
};

void doSomething(Abstract *a)
{

}

int main()
{
Concrete c;

for(auto& object : c.children())
doSomething(object);
}


In other words, my Concrete objects own instances of their own class as children. Other code wants to treat them as their Abstract base class. I can think of a few ways to achieve this, but I'm struggling to find an elegant one. It'd be nice if my classes supported iteration, but I can't get it to work with virtual abstract functions. I tried this:


(in Abstract)



virtual std::vector<const Abstract *>::const_iterator begin() const = 0;
virtual std::vector<const Abstract *>::const_iterator end() const = 0;
virtual std::vector<Abstract *>::iterator begin() = 0;
virtual std::vector<Abstract *>::iterator end() = 0;


, but what do I do in Concrete::begin() (where m_ children is declared as



m_children std::vector<Concrete *>


)? I began thus:



std::vector<const Abstract *>::const_iterator it;
Abstract *first = *m_children.begin();


... thinking that I might be able to have "it" point to the first instance in my vector. Here's where I'm stumped.


Suggestions appreciated!


Aucun commentaire:

Enregistrer un commentaire