Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Abstract class destructor not called 1

Status
Not open for further replies.

sedj

Programmer
Aug 6, 2002
5,610
Hello,

Can someone explain why the destructor does not seem to be called ?
The output is :

construct
Hello

But the "destruct" is not present. I'm clearly missing a fundamental point in abstract C++ classes - can someone tell me what ?

Thanks

Code:
#include <stdio.h>

// the abstract class
class AbstractClass {
public:
	virtual void sayHello() = 0;
};

// an implementation
class ClassImpl : public AbstractClass {
public:
	ClassImpl() {
		printf("construct\n");
	}

	~ClassImpl() {
		printf("destruct\n");
	}

	void sayHello() {
		printf("Hello\n");
	}
};

// run the test
int main() {
	AbstractClass* qqq = new ClassImpl();
	qqq->sayHello();
	delete(qqq);
}
 
Your pointer qqq is to the AbstractClass which does not have a defined destructor. If you change your pointer to point to the ClassImpl class the destructor you have will fire.

If you choose to battle wits with the witless be prepared to lose.

[cheers]
 
Hi,

Apparently, you have to declare the destructor of AbstractClass as virtual, so that descendant classes can redefine it.

Code:
// the abstract class
class AbstractClass {
public:
    virtual ~AbstractClass() {
    }

    virtual void sayHello() = 0;
};

--
Globos
 
Foada,
I need to have the pointer as the AbstractClass, because I need to define different behaviour in the implementing classes, but call the same method signature.

Globos,
Thankyou, that did the trick.

I find it a bit odd though, because if (just for arguments sake), I declared a "virtual constructor" aswell, I get an "only constructors declared as inline are legal" error.
Ah well, the solution works, so that'll do me :)

--------------------------------------------------
Free Java/J2EE Database Connection Pooling Software
 
You cannot make constructors virtual in C++, and it would make no sense to do so.

The virtual keyword in the base class function indicates that when this function is called from a base class pointer or reference, the actual derived type pointed to is checked (along with derived classes in between if there is a long hierarchy) for an implementation of that function, and if the function is implemented there, it is called.

In this case, the destructor is called when the object is deleted, but since you are deleting it through a base class pointer, the base class destructor is called. Since in your original code you didn't define a destructor, the default version was chosen, and the default version is not virtual.

In fact, your original code invoked undefined behavior - it is against the rules to delete a derived class through a base class pointer if the base class destructor is not virtual.

For any and every class you want to use polymorphically as a base class, you should declare the destructor as virtual. Usually for abstract classes like yours, the destructor is made pure virtual, although in the special case of the destructor you must implement it as well (even if it's empty). So I would do this:
Code:
// the abstract class
class AbstractClass {
public:
    virtual ~AbstractClass() = 0 { };
    virtual void sayHello() = 0;
};
Making the constructor virtual doesn't make sense because the constructor is called only when you create an object, and you already know the dynamic type of the object when you are creating it.


Hmmm... IonFilipski in the Java forum and sedj in the C++ forum... what's going on here? ;-)
 
sedj,

I guess I should have worded my answer differently. I stated
Your pointer qqq is to the AbstractClass which does not have a defined destructor
and then I went on to explain how you could get the destructor to fire with the given class definitions. The reason has to do with the way the compiler handles implicit destructors, by explicitly declaring your AbstractClass destructor, the compiler will call the derived class destructor. Sorry for not being more clear.

If you choose to battle wits with the witless be prepared to lose.

[cheers]
 
Thank you all for your help, I appreciate it.

Its nice to be the questioner for once and get a decent answer :)

uolj, thanks especially for the defined explanation - thats just the kind of indepth answer I was after.

--------------------------------------------------
Free Java/J2EE Database Connection Pooling Software
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top