Вектор указателей на абстрактный класс для доступа к производным членам класса - PullRequest
4 голосов
/ 12 декабря 2010


Я новичок в C ++ и пытаюсь реализовать эмулятор черепахи, который будет читать команды из текстового файла, помещать их в вектор и рисовать их, используя glut
У меня есть класс узла, класс команд, полученный из узла, 4 производных класса (вперед, влево, вправо, переход, повтор) из команды и класс Prog, который используется для хранения команд.

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

и

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

прямо сейчас мы можем читать из файла и записывать команды во временном векторе, а затем их значения. Например, повтор должен повторить 4 раза следующие команды | Повторение | 4 | вперед | 4 | влево | 40 | вперед | 10
мы хотим добавить в вектор листинга внутри указателей на классы Prog объекты базового класса, которые будут использоваться для вызова функции Run из 4 производных классов и использования полиморфизма
Моя проблема в том, что я использую некоторое время, чтобы пройти через свой временный вектор и создать объект для каждой команды, которую я нахожу, но я могу использовать только одно и то же имя, поскольку динамическое именование не может быть использовано (я думаю), и я думаю, что каждая новая Команда вперед перезапишет объект fw

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

Я пытался использовать что-то вроде ниже, но не мог найти правильный путь

    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);*/

}

есть ли способ сделать то, что я хочу ?? в конце мы хотим вызвать Prog :: Run это будет выглядеть примерно так

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

также кое-что о функциях друзей, которые я объявил, и я не уверен, что это правильно: Я определил friend istream& operator>> (istream& in, Prog& pro); в классе Prog и только что объявил его в двух других классах, или мне нужно определить его для каждого класса и иметь разные вторые аргументы в каждом классе ??
заранее спасибо :) 1024 *

1 Ответ

2 голосов
/ 12 декабря 2010

Исходя из того, что вы описываете, pro.push_back( new Forward(value) ); - это то, что вы ищете.

Кроме того, функция или класс должны быть объявлены как друзья в каждом классе, к которому будут иметь доступ не частные члены.это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...