pmantz
pmantz

Reputation: 67

Vector of pointers to abstract class,to access derived class members


I'm new to C++ and trying to implement a turtle emulator that will read commands from a text file, put them on a vector and draw them using glut
I have node class,command class derived from node, 4 derived classes(forward,left,right,jump,repeat) from command and Prog class that is used to store commands.

class node
{
    public:
        node();
        virtual ~node();
        virtual void Run()=0;
};

class command : public node
{
    private:
        float v;
    public:
        command();
        command(float);
        ~command();
        virtual void Run();
        friend istream& Prog::operator>> (istream& in, Prog& pro);
};

and

class Repeat : public command
{
    private:
        Prog pg;
    public:
        Repeat(float value, istream& in);
        ~Repeat();
        void Run();
        friend istream& Prog::operator>> (istream& in, Prog& pro);
};

class Prog
{
    private:
        vector<node*> listing;
    public:
        Prog();
        ~Prog();
        void Run();
        friend istream& operator>> (istream& in, Prog& pro);
};

right now we are able to read from a file and write commands in a temp vector, followed by their values.for example repeat should repeat 4 times the following commands |repeat|4|forward|4|left|40|forward|10
we want to add in the listing vector inside Prog class pointers to base class objects, that would be used to call Run function of the 4 derived classes and make use of polymorphism
my problem is that i use a while to go through my temp vector, and create an object for each command I find, but I can only use the same name, since dynamic naming cant be used(i think) and I think that each new Forward command will overwrite fw object

    else if (command=="FORWARD")
    {
        Forward::Forward fw(value);
        node* ptr;
        ptr= &fw;
        pro.push_back(ptr);
        text.erase (text.begin(), text.begin()+2);*/
    }

I tried to use something like below but could n't find a correct way

    else if (command=="FORWARD")
    {
        Forward::Forward fw(value);
        new Forward(fw);
        node* ptr;
        ptr= &(??);
        pro.push_back(ptr);
        text.erase (text.begin(), text.begin()+2);*/

}

is there a way to do what I want?? in the end we want to call Prog::Run that will look something like this

void Prog::Run()
{
        vector<node*>::iterator it;
        for (it=listing.begin();it!=listing.end();it++)
        listing[it]->Run();
}

also something about the friends functions I have declared and im not quit sure if it's right: I defined friend istream& operator>> (istream& in, Prog& pro); on Prog class and just declared it in the other 2 classes or I need to define it for each class and have a different second argument in each class??
thanks in advance:)

Upvotes: 4

Views: 2501

Answers (1)

Victor Nicollet
Victor Nicollet

Reputation: 24577

Based on what you describe, pro.push_back( new Forward(value) ); is what you're looking for.

Also, a function or class must be declared as friend in every class that will have non-private members be accessed by it.

Upvotes: 2

Related Questions