2016-04-29 3 views
0

У меня есть очередь, содержащая объекты класса Event.Функциональный полиморфизм с ссылочными данными Тип

std::priority_queue<Event> events; 

Но событие - это просто суперкласс реальных событий. Давайте предположим, что мы имеем следующие классы:

class Event{ 
    public: 
    void Action(){ 
     std::cout<<"do nothing"<<std::endl; 
    } 
}; 

class XEvent : public Event{ 
    public: 
    void Action(){ 
      std::cout<<"do x"<<std::endl; 
    } 

class YEvent : public Event{ 
    public: 
    void Action(){ 
      std::cout<<"do y"<<std::endl; 
    } 
}; 

и в главной функции:

int main(){ 
    std::vector<Event> events; 
    events.push_back(XEvent x); 
    events.push_back(YEvent y); 
    Event e = events[0]; 
    e.Action(); 
} 

хочу e.Action вести себя в соответствии с перегруженной версии. (т. Е. «Делать x»).

Но вместо этого выход дает мне «ничего не делать». Любое предложение?

p.s. Im фактически ищет способ сделать это без использования указателей

+0

Читайте о нарезания. Вектор должен быть «std :: vector > события; скорее. –

ответ

0

Вставка в вектор копирует элемент. Тип цели всегда Event, заданный как параметр шаблону, поэтому это изменяет тип.

Предложения:

  • Используйте std::function вместо. Это может быть именно то, что вы ищете для обработки событий.
  • Вместо этого используйте (умный) указатель, поэтому вы можете хранить полиморфные элементы.
  • Используйте вместо этого интеллектуальный тип соединения/варианта, например. Boost.Any или Boost.Variant (не уверен, что любой из них стандартизован к настоящему времени).
0
class Event{ 
    public: 
    virtual void Action(){ 
     std::cout<<"do nothing"<<std::endl; 
    } 
}; 

использование виртуальной функции, как описано выше, но вы создали объект, который из класса Event может быть, вы должны создать указатель;

int main(){ 
    std::vector<Event> events; 
    events.push_back(XEvent x); 
    events.push_back(YEvent y); 
    XEvent xe = events[0]; 
    Event* e = &xe; 
    e->Action(); 
} 

или осуществить литье objrct.

+0

Проблема с этим решением состоит в том, что в общем случае я не знаю, какие события события будут [i], поэтому я не могу сделать XEvent xe = events [i]; – finaleblue

+0

использовать оператор-оператор, например Event * e = static_cast xe – CMLDMR

0

использование смарт-указатель общий указатель, попробуйте парование код:

#include<iostream> 
#include<vector> 
#include <memory> 

class Event{ 
    public: 
    virtual void Action(){ 
     std::cout<<"do nothing"<<std::endl; 
    } 
}; 

class XEvent : public Event{ 
    public: 
    void Action(){ 
      std::cout<<"do x"<<std::endl; 
    } 
}; 

class YEvent : public Event{ 
    public: 
    void Action(){ 
      std::cout<<"do y"<<std::endl; 
    } 
}; 
int main(){ 
    std::vector<std::shared_ptr<Event>> events; 
    events.push_back(std::make_shared<XEvent>()); 
    events.push_back(std::make_shared<YEvent>()); 
    std::shared_ptr<Event> e = events[0]; 
    e->Action(); 
    return 0; 
} 
Смежные вопросы