Hello ladies and gents,

Ive been reading about Virtual Function in my book and there is this programming that shows how and what happens, I understand what is happening but one thing that came to my mind is that, previously in my book, there was mentioned that you should allways "delete" the memory that was allocated with "new". However, this is not done in this program and I understand why, it's just a small program to show the virtual function.

Still, I was wondering how one would do this as the memory allocation is done for an Array of Mammals :?:

#include <iostream>

class Mammal
{
public:
	Mammal():itsAge(1) {}
	~Mammal() {}

	virtual void Speak() const { std::cout<<"Mammal speak!\n";}

protected:
	int itsAge;
};

class Dog : public Mammal
{
public:
	void Speak() const { std::cout<<"Woof!\n";}
};

class Cat : public Mammal
{
	void Speak() const { std::cout<<"Meow!\n";}
};

class Horse : public Mammal
{
	void Speak() const { std::cout<<"Hihihi!\n";}
};

class Pig : public Mammal
{
	void Speak() const { std::cout<<"Oinkoink!\n";}
};

int main()
{
	Mammal *theArray[5];
	Mammal *ptr;

	int choice, i;

	for( i = 0; i < 5; i++)
	{
		std::cout<<"(1)dog (2)cat (3) horse (4) pig: ";
		std::cin>> choice;

		switch(choice)
		{
		case 1:
			ptr = new Dog;
			break;
		case 2:
			ptr = new Cat;
			break;
		case 3:
			ptr = new Horse;
			break;
		case 4:
			ptr = new Pig;
			break;
		default:
			ptr = new Mammal;
			break;
		}

		theArray[i] = ptr;
	}

	for( i = 0; i < 5; i++)
		theArray[i]->Speak();

	return 0;
}

As you can see, depending on wich number you enter, memory is allocated for a certain class function, however, all memory is allocated into theArray, so I tried the following

for( i = 0; i < 5; i++)
     delete [i] theArray;

But, this is giving me the following error:

warning C4154: deletion of an array expression; conversion to pointer supplied

Can any of you help me out here, thanks :)

brackets are in the wrong place

for( i = 0; i < 5; i++)
     delete theArray[i];

Darn :mrgreen:

Thanks Ancient Dragon ;)

also, add destructors to each class and you will see how they behave too

#include <iostream>
using namespace std;

class Mammal
{
public:
	Mammal():itsAge(1) {}
	virtual ~Mammal() { cout << "Mammel destructor" << endl;}

	virtual void Speak() const { std::cout<<"Mammal speak!\n";}

protected:
	int itsAge;
};

class Dog : public Mammal
{
public:
	virtual ~Dog() { cout << "Dog destructor" << endl;}
	void Speak() const { std::cout<<"Woof!\n";}
};

class Cat : public Mammal
{
	virtual ~Cat() { cout << "Cat destructor" << endl;}
	void Speak() const { std::cout<<"Meow!\n";}
};

class Horse : public Mammal
{
	virtual ~Horse() { cout << "Horse destructor" << endl;}
	void Speak() const { std::cout<<"Hihihi!\n";}
};

class Pig : public Mammal
{
	virtual ~Pig() { cout << "Pig destructor" << endl;}
	void Speak() const { std::cout<<"Oinkoink!\n";}
};

int main()
{
	Mammal *theArray[5];
	Mammal *ptr;

	int choice, i;

	for( i = 0; i < 5; i++)
	{
//		std::cout<<"(1)dog (2)cat (3) horse (4) pig: ";
//		std::cin>> choice;
choice = i+1;
		switch(choice)
		{
		case 1:
			ptr = new Dog;
			break;
		case 2:
			ptr = new Cat;
			break;
		case 3:
			ptr = new Horse;
			break;
		case 4:
			ptr = new Pig;
			break;
		default:
			ptr = new Mammal;
			break;
		}

		theArray[i] = ptr;
	}

	for( i = 0; i < 5; i++)
		theArray[i]->Speak();

	for( i = 0; i < 5; i++)
		delete theArray[i];
	return 0;
}

Wow, just noticed that the Mammals destructor is allways called, is this because Mammal is the base class and it has the virtual Speak(); function :?:

Hmmm, think I'm wrong here, think it's got to do with the fact that theArray is an object to Mammal, therefore, deleting theArray's memory is linked towards the Mammal's destructor right :?:

for( i = 0; i < 5; i++)
delete theArray;

You shouldn't need the for loop, should just be able to do this once:

delete [] theArray;

I think you need to delete ptr; as well...

Also, I believe it should be:
ptr = new Dog();
instead of
ptr = new Dog;
...etc..

?

well, the allocating is done for every separate class (dog, cat, horse, ...) so, they aren't separate functions but, separate classes wich have Mammal as there base class.

Using the for loop, haven't I deleted every memory allocation that was used for the new pointers? So, why should I delete the ptr aswell, it was stored in the array, or am I wrong at this?

Could be winbatch, just trying to figure this out you know :)

You shouldn't need the for loop, should just be able to do this once:

delete [] theArray;

that will not work in his program because theArray is an array of pointers, which are allocated separately, so each one has to be deleted separately.

Mammel destructor is always called because it is the base class of all other children. so it has to destroy any allocated memory that it may have created. If it was not called then there might be a memory leak.

no because the address is always copied into theArray, so deleting theArray will also delete the memory that was allocated for ptr.

Also, I believe it should be:
ptr = new Dog();
instead of
ptr = new Dog;

Either way is ok -- I normally do not use parentheses when there is nothing to put in them.

I do that a lot too :lol:

And I thought you guys didn't have anything left to learn :lol:

And I thought you guys didn't have anything left to learn :lol:

:cheesy: :cheesy: you can always teach an old dog new tricks. writing c and c++ is a life-long learning experience. Those college degrees only give you the tools to begin learning.

This article has been dead for over six months. Start a new discussion instead.