关于StackOverflow的第一个问题。我要为我的英语不好而道歉。
我实际上是在为电子游戏开发菜单。我想清除代码,所以我想使用vector调用不同的功能(例如为图片充电或修改文本)
这是代码:
Menu.hh:
class Menu
{
int _position
std::vector<Menu> _graph;
std::list<sf::Text> _text;
public:
//constructors and destructors
virtual std::list<sf::Text> &modifyText();
}
Menu.cpp
std::list<sf::Text> &modifyText()
{
std::cout << this->_position << std::endl;
this->_text = this->_graph[this->_position].modifyText();
return (this->_text); // don't care of the return
}
void Menu::initGame()
{
this->_graph.push_back(MenuBase());
// if i Put this code on the constructor, the constructor call himself and not the MenuBase constructor
this->modifyText();
}
MenuBase.hpp
class MenuBase : public Menu
{
//constructor and destructor
std::list<sf::Text &modifyText(){std::cout << "work" << std::endl;
//I've more code, but it's just initialization of text and the return.
//The work is here to show what's happen on the standard output.
}
该代码的输出是:0、0,然后是SegFault。我希望在标准输出上看到“0”然后“工作”。
那么,为什么不调用MenuBase函数呢?
要获得完整的代码,这是gitHub存储库:https://github.com/Aridjar/AW_like
最佳答案
您看到的称为Object Slicing。当您将MenuBase
对象放入Menu
对象的 vector 容器中时,Base
类中不存在的任何功能都会“切断”您的对象。仅保留基类的功能。对象的行为不再是多态的,超出了放入容器的类的范围。
为了保持所需的多态行为,请用指针容器替换对象容器。为了避免手动内存管理带来麻烦,最好将智能指针改为常规指针:
std::vector< std::shared_ptr<Menu> > _graph;