I'm using a list to store objects of different classes, which have a common base class. Moreover when I access directly an element of the list, I need to use late binding to call the override functions inside the derived class.
The compiler (or C++) does not let me to do so.
#include <iostream>
#include <list>
class PowerUp { //Base class
public:
virtualvoid activate() {std::cerr<<"wrong function"<<std::endl;}
};
class Large : public PowerUp { //Derived class
public:
void activate(); //overriden function
};
void Large::activate() {
std::cerr<<"good!!"<<std::cerr;
}
int main() {
std::list<PowerUp> powers; //list with the objects
PowerUp * pointer;
pointer = newclass Large; //create an object of type Large
std::cerr<<typeid((*pointer)).name()<<std::endl;
powers.push_front(*pointer); //push the object into the list
std::cerr<<typeid((powers.front())).name()<<std::endl;
for (auto it = powers.begin(); it != powers.end(); ++it) {
it->activate(); //call the function
std::cerr<<typeid((*it)).name()<<std::endl;
}
return 0;
}
When running this code I get this output:
1 2 3 4
5Large
7PowerUp
wrong function
7PowerUp
Why does the object change type when I push it into the list?
Is there a way of fixing it?
I do need to store objects somewhere and I cannot have a list for each different type of object. I would like to avoid using casting on pointers since it's annoying to code a huge switch statement with all the possible derived classes.
#include <iostream>
#include <list>
#include <typeinfo>
class PowerUp { //Base class
public:
virtualvoid activate() {std::cout<<"wrong function"<<std::endl;}
};
class Large : public PowerUp { //Derived class
public:
void activate(); //overriden function
};
void Large::activate() {
std::cout<<"good!!"<<std::endl;
}
int main() {
std::list<PowerUp*> powers; //list of POINTERS TO the objects
PowerUp * pointer;
pointer = new Large; //create an object of type Large
std::cout<<typeid(*pointer).name()<<std::endl;
powers.push_front(pointer); //push the (pointer to the) object into the list
std::cout<<typeid(*powers.front()).name()<<std::endl;
for (auto it = powers.begin(); it != powers.end(); ++it) {
(*it)->activate(); //call the function
std::cout<<typeid(*(*it)).name()<<std::endl;
}
return 0;
}
I thought this would have not worked because in my project the construction of the object happens in a method function and I was worried that the compiler would destroy the object created when the function call ends, but I was wrong.