Late binding in a list

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <list>

class PowerUp { //Base class
public:
	virtual void 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 = new class 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.

Thanks in advance for any help.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <list>
#include <typeinfo>

class PowerUp { //Base class
public:
        virtual void 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;
}

5Large
5Large
good!!
5Large
Last edited on
Thanks a lot.

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.
Topic archived. No new replies allowed.