Calling virtual method from derived class in vector of base class c++

c++, c++11, xcode

Solution

Much of the value of inheritance is lost when you create an object on the stack instead of the heap. Virtual functions is one of the things that you lose, if you want the virtual function to call the right function you must pass the object as pointer or a reference and use `new` to create it.

Base * b = new Derived();    // or  
Base & b = * new Derived();  

The vector must store a reference or a pointer.

vector<BaseClass*> classes;
vector<BaseClass&> classes;

By popular demand the easiest way to handle this is `std::shared_ptr`

vector<shared_ptr<BaseClass>> classes;

One of these would be created like so:

shared_ptr<BaseClass> ptr(new BaseClass);

Basically a shared_ptr will handle the annoying task of memory management

shared_ptr is good if you need multiple ptr's to the same object, if not you can use `std::unique_ptr`

`vector<unique_ptr<BaseClass>> classes;`

create like this:

`unique_ptr<BaseClass> ptr(new BaseClass);`

As you can see the syntax is very similar to shared_ptr so the transition is easy

Problem

Inside a class BaseClass I have a public function: ``` virtual void Call(){}; ``` Inside of a derived class Archer I have the function: ``` void Call(){ cout << "whatever" << endl; }; ``` I also have a vector set up: ``` vector<BaseClass> classes; ``` wherein I push 3 classes derived from BaseClass. The problem seems (to me, I'm probably wrong) to be that I am calling Call() from a reference to BaseClass even though I push them into the vector through a method like: ``` BaseClass Player::CharChoice(string character) { if(character == "Archer") return *new Archer(); else if(character == "Knight") return *new Knight(); else if(character == "Sorcerer") return *new Sorcerer(); else cerr << "CHARACTER NOT DEFINED" << endl; }; for(int c = 0; c < chars.size(); c++) { classes.push_back(CharChoice(chars[c])); } ``` If I instead set up a variable such as: ``` Archer *archer = new Archer(); ``` and call Call(), it works how I would intend. I'm fairly new to C++ and cannot think up a solution to this.

Original source

Related problems