1

First question on StackOverflow. And I want apologize for my bad English.

I'm actually developing a menu for a video game. I want clear the code, so I want use vector to call different functions (like charge a picture or modify the text)

here's the code :

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.
}

The ouptut of this code is : 0, 0 then SegFault. I expect to see "0" then "work" on standard output. So, why the MenuBase function is not called ?

To have the full code, here's the gitHub repository : https://github.com/Aridjar/AW_like

OMGtechy
  • 7,935
  • 8
  • 48
  • 83
Aridjar
  • 301
  • 1
  • 5
  • 14
  • Make sure you're copying and pasting the code, as some of this shouldn't even compile. Also, it appears you're using SFML, so I've added that tag. – OMGtechy Jul 31 '14 at 12:47
  • Output of what code (i.e., where is your entry-point)? – barak manos Jul 31 '14 at 12:48
  • Try using override keyword to make sure the virtual function is overloading something. This helps protect against typos. – Neil Kirk Jul 31 '14 at 12:50
  • about your comment in `Menu::initGame`: virtual functions are not polymorphic during construction. See here: http://stackoverflow.com/questions/962132/calling-virtual-functions-inside-constructors – king_nak Jul 31 '14 at 12:58

1 Answers1

8

What you see is called Object Slicing. When you put your MenuBase objects in a vector container of Menu objects, any functionality not present in the Base class is "sliced off" your object; only the functionality of the base class remains. The behavior of your objects stops being polymorphic beyond the bounds of the class that you put in the container.

In order to keep the polymorphic behavior that you want, replace the container of objects with a container of pointers. To avoid headaches with manual memory management, prefer smart pointers to regular ones:

std::vector< std::shared_ptr<Menu> > _graph;
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523