Исключение шаблона состояния C++

Я новичок в С++! Пожалуйста, помогите мне реализовать шаблон состояния.

У меня есть код ниже, но он не компилируется:

class MasterThreadState;
class Init; class Idle;

class MasterThread
{
public:
    MasterThread(){
        _state = Init::State();
    }
    void handle(int sender, int tag);
private:
    int _sender;
    MasterThreadState* _state;
private:
    friend class MasterThreadState;
    void goTo(MasterThreadState* newState){ _state = newState; }
};

class MasterThreadState
{
public:
    virtual void recieved(MasterThread& master, int tag);
protected:
    void goTo(MasterThread& m, MasterThreadState* newState){
        m.goTo(newState);
    }
};

class Init : MasterThreadState {
public:
    static MasterThreadState& State() { return instance; }
    virtual void recieved(MasterThread& master, int tag);
private:
    static Init instance;
};

class Idle : MasterThreadState {
public:
    void recieved(MasterThread& master,int tag);
    static MasterThreadState& State(){ return instance; }
private:
    static Idle instance;
};

Ошибка:

неполный тип 'Init', используемый во вложенном спецификаторе имени _state = Init::State();


person user2621486    schedule 06.08.2015    source источник
comment
Вы не можете использовать Init только с предварительным объявлением, которое будет возвращено по значению, вместо этого используйте указатель или ссылку. Вы все равно не хотите иметь копию состояния.   -  person πάντα ῥεῖ    schedule 06.08.2015
comment
Спасибо за ответ, но можете ли вы показать, какой фрагмент кода мне нужно изменить?   -  person user2621486    schedule 06.08.2015
comment
поместите определение MasterThread::MasterThread после определения Init.   -  person Jarod42    schedule 06.08.2015
comment
Когда я это делаю, я поймал ошибку: неопределенная ссылка на `vtable for Init'   -  person user2621486    schedule 06.08.2015


Ответы (2)


Виртуальная функция не была реализована

Этот код работает нормально:

class MasterThreadState;
class Init; //class Idle;

class MasterThread
{
public:
    MasterThread();
    void handle(int sender, int tag);
private:
    int _sender;
    MasterThreadState* _state;
private:
    friend class MasterThreadState;
    void goTo(MasterThreadState* newState){ _state = newState; }
};

class MasterThreadState
{
public:
    virtual void recieved(MasterThread& master, int tag) = 0;
protected:
    void goTo(MasterThread& m, MasterThreadState* newState){
        m.goTo(newState);
    }
};

class Init : MasterThreadState {
public:
    static MasterThreadState* State();
    virtual void recieved(MasterThread& master, int tag);
private:
    Init(){}
};

class Idle : MasterThreadState {
public:
    static MasterThreadState* State();
    virtual void recieved(MasterThread& master,int tag);
private:
    static Idle instance;
};
person user2621486    schedule 06.08.2015
comment
Нереализованная функция может вызвать ошибку компоновщика, а не компилятора. Исправлено определение MasterThread::MasterThread() вне строки, где было доступно полное объявление Init. - person Quentin; 06.08.2015

Если переместить конструктор MasterThread после объявления Init, код будет скомпилирован (и построен):

class MasterThread
{
public:
    MasterThread();
    void handle(int sender, int tag);
private:
    int _sender;
    MasterThreadState* _state;
private:
    friend class MasterThreadState;
    void goTo(MasterThreadState* newState){ _state = newState; }
};

class MasterThreadState
{
public:
    virtual void recieved(MasterThread& master, int tag) {}
protected:
    void goTo(MasterThread& m, MasterThreadState* newState){
        m.goTo(newState);
    }
};

class Init : MasterThreadState {
public:
    static MasterThreadState* State() { return &instance; }
    virtual void recieved(MasterThread& master, int tag) {}
private:
    static Init instance;
};

Init Init::instance;

MasterThread::MasterThread() {
    _state = Init::State();
}

Обратите внимание, что Init::State() должен возвращать указатель MasterThreadState*. Это также было изменено, определен статический член Init::instance и добавлена ​​реализация (пустая) виртуальных функций для правильной компоновки.

person Spock77    schedule 06.08.2015