关于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;

09-25 17:02