2016-05-21 2 views
1

Эта программа представляет собой игру, в которой динамическая доска массива 2d заполнена классами комнат. В каждом классе комнаты есть класс событий с отдельным указателем, который наследует один из четырех разных дочерних классов. Моя цель - иметь виртуальные функции класса событий в каждом дочернем классе, чтобы я мог вызвать чистую виртуальную функцию в событии, которое вернет строку из унаследованного дочернего класса. Однако я получаю ошибку с ошибкой seg. Вот мой упрощенный код:segfault при ссылке на виртуальную функцию в классе указателя

//in game class 
    board[1][1].set_bat(); 
    board[1][1].get_message(); 

//room.h 
    class room { 
     private: 
     event *ev; //here, each room class is given an event class pointer 
    public: 
     void set_bat(); 
     void get_message(); 

    }; 

//in room.cpp 
    void room::set_bat(){ //here, the event pointer is set to one of its child classes. 
     bats x; 
     ev = &x; 
     //ev->message(); if the message func is called here, it return "bats" correctly, 
    } 
    void room::get_message(){ //calling this, is where the error occurs 
     ev->message(); 
    } 

//in event.h 
    class event { 
     public: 
      virtual void message() = 0; 
    }; 

//in bats.h 
    class bats: public event{ 
    public: 
     void message(); 
    }; 

//in bats.cpp 
    void bats::message(){ 
     cout<<"bats"<<endl; 
    } 

Конечная цель будет для всякий раз, когда я называю get_message в классе игры, он будет возвращать строку из виртуальной функции, даже если событие в комнате было что-то другое, например как яму, где она вернет строку «яма».

ответ

0

В:

void room::set_bat(){ //here, the event pointer is set to one of its child classes. 
    bats x; 
    ev = &x; 
    //ev->message(); if the message func is called here, it return "bats" correctly, 
} 

Вы возвращаете указатель на локальную переменную. Эта переменная выходит за пределы области действия, когда функция возвращается, и, следовательно, ev теперь указывает на мусор.
Вы должны использовать new для выделяющих указателей:

void room::set_bat(){ 
    ev = new bats(); 
} 

Это также означает, что вы должны определить деструктор для room класса, который вызывает delete ev:

class room { 
    private: 
    event *ev; //here, each room class is given an event class pointer 
public: 
    void set_bat(); 
    void get_message(); 
    ~room() { delete ev; } // ADDED 
}; 
+0

Спасибо! Это имеет смысл, и я вижу, как то, что я делаю, было неправильным. – Martin

Смежные вопросы