Member Avatar for Nahdir

Hello,

I am having trouble with using polymorphism:

#include <list>
#include <iostream>

class a {
virtual void foo() { std::cout << "a" };
}

class b {
void foo() { std::cout << "b" };

std::list<a> listOfA;

b objectOfB;

listOfA.push_front(objectOfB);

for (std::list<a>::iterator it = listOfA.begin(); it != listOfA.end(); ++it)
    it->foo();

I would like this code to produce "b" as output, but in my code i always get "a". Could anyone point me to the problem/solution/alternative? I cant seem to find one using search. BTW this is in a context of storing objects derived from a base class i.e. bullets, players, enemies, bricks etc. in a tank game.

Your help is greatly appreciated.

Personally I would start with just using a single variable instead of trying to make a list work because that just adds more complexity to something that you are trying to figure out. And if you are going to then just use the std namespace to shorten and clean the lines up until you learn it, then go back to adding the scope if you want to remove it.

Polymorphism is a special feature of inheritance, meaning you need to inherit class a into class b.

Also in order for this to work you need to make a list of pointers to an "a" class instead of having a list of instances of the "a" class otherwise it just outputs the character a because class "a" can be its own instance. You can change it so that class "a" is a pure virtual class by putting virtual void foo()=0; in class "a" but the usage is the same.

Here is the code using the virtual function foo() and not a pure-virtual function.

#include <iostream>
#include <list>
using namespace std;

class a
{
	public:
	virtual void foo()
	{
		cout << "a";
	}
};

class b: public a //inherit class a
{
	public:
	void foo()
	{
		cout << "b";
	}
};

int main()
{
	list<a*> listOfA;
	b objectOfB;
	listOfA.push_front(&objectOfB);

	list<a*>::iterator it;
	for ( it = listOfA.begin(); it != listOfA.end(); it++)
		(*it)->foo();

	return 0;
}
Member Avatar for Nahdir

Personally I would start with just using a single variable instead of trying to make a list work because that just adds more complexity to something that you are trying to figure out. And if you are going to then just use the std namespace to shorten and clean the lines up until you learn it, then go back to adding the scope if you want to remove it.

Thanks for the suggestion. I did use a single object until i approached a point where i think i need to use a list. As for the namespace, i would like to get into the habbit of actually specifying the scope. Dont know if thats a good or a bad ting. I have used namespace in the past.

Polymorphism is a special feature of inheritance, meaning you need to inherit class a into class b.

Also in order for this to work you need to make a list of pointers to an "a" class instead of having a list of instances of the "a" class otherwise it just outputs the character a because class "a" can be its own instance. You can change it so that class "a" is a pure virtual class by putting virtual void foo()=0; in class "a" but the usage is the same.

Here is the code using the virtual function foo() and not a pure-virtual function.

#include <iostream>
#include <list>
using namespace std;

class a
{
	public:
	virtual void foo()
	{
		cout << "a";
	}
};

class b: public a //inherit class a
{
	public:
	void foo()
	{
		cout << "b";
	}
};

int main()
{
	list<a*> listOfA;
	b objectOfB;
	listOfA.push_front(&objectOfB);

	list<a*>::iterator it;
	for ( it = listOfA.begin(); it != listOfA.end(); it++)
		(*it)->foo();

	return 0;
}

Thanks a lot for this explanation. My mistake was what you pointed out. I incorrectly had a list of instances of "a" class. When i changed it to

list<a*> listOfA;

and did the relevant changes elsewhere the code threw an error because i was accessing an ?empty pointer?. I realised that the object "b" created was destroyed before it was accessed (because it was local in a separate function, i forgot to mention this). So i initialised it like this

a* b = new b();

and now it works.

Thanks a lot for this explanation and solution. This was bugging me for a few weeks now.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.