Sign in to follow this  

C++ empty constructor/destructor questions

This topic is 3294 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've got a few questions about empty constructors/destructors when inheritance is concerned. I've googled this, and have read the C++ FAQ Lite entries, but they seem a bit vague on the following questions. I'm hoping someone here will know for sure what the best practice is. 1. I have a non-abstract base class, from which several other classes derive. I do a lot of casing to the base class, and so my base class has a virtual destructor. However, that destructor is empty and unused. My question is, if the base class's destructor is empty, is it still important to define it, just to make sure it is virtual? 2. Same for constructors. If a base class has an empty constructor, does it still need to be defined in the base class? 3. Likewise, if a derived class contains an empty constructor or destructor, do they need to exist just to inherit from the base class, or can either or both be safely left undefined?

Share this post


Link to post
Share on other sites
Quote:
Original post by Nairou
1. I have a non-abstract base class, from which several other classes derive. I do a lot of casing to the base class, and so my base class has a virtual destructor. However, that destructor is empty and unused. My question is, if the base class's destructor is empty, is it still important to define it, just to make sure it is virtual?


Yes - default destructors are non-virtual.

Quote:

2. Same for constructors. If a base class has an empty constructor, does it still need to be defined in the base class?


No.

Quote:

3. Likewise, if a derived class contains an empty constructor or destructor, do they need to exist just to inherit from the base class, or can either or both be safely left undefined?


Both can be left out.

Share this post


Link to post
Share on other sites
Just as a side note to that, constructors are not inherited. If you want "virtual constructor" behaviour, you are going to have to fake it. (In particular, it is common to use a named virtual member function called 'clone', or something like that, in order to get the effect of a "virtual copy constructor", as the actual copy constructor can't do that. This is typically implemented by redefining it in each class to call the current class' copy constructor. Annoying bit of boilerplate, yes. Sorry.)

Share this post


Link to post
Share on other sites
Quote:
Original post by Driv3MeFar
Quote:
Original post by Nairou
Quote:

2. Same for constructors. If a base class has an empty constructor, does it still need to be defined in the base class?


No.
Actually it depends...
If you have non-default constructors, and you delete the default constructor, then a default constructor will not longer be auto-generated, and if you happen to be using the default constructor anywhere then boom - it won't compile.
So in some cases, explicitly defining an empty default constructor can be necessary.

Share this post


Link to post
Share on other sites
Quote:
Original post by Nairou
1. I have a non-abstract base class, from which several other classes derive. I do a lot of casing to the base class, and so my base class has a virtual destructor. However, that destructor is empty and unused. My question is, if the base class's destructor is empty, is it still important to define it, just to make sure it is virtual?

Here are some rules about the topic:

A. First and most important, define it, no conditions. Virtual destructor means (for me and at least a few others) "I am a base class".
B. You don't need a virtual empty destructor until you delete a pointer to a base class with different dynamic type, and that dynamic type has some member variables or a non-empty destructor. I.e. "Base* b = new Derived(); delete b;" does not invoke ~Derived() and does not delete the members of Derived, but calls ~Base() and deletes the members of Base (calls their destructors and releases the memory where they were allocated).


Quote:
Original post by Nairou
3. Likewise, if a derived class contains an empty constructor or destructor, do they need to exist just to inherit from the base class, or can either or both be safely left undefined?

Constructors and destructors are never undefined. They may be automatically generated. Constructors are never virtual. Destructors must be declared virtual when you want to (safely) inherit from them (see comment above).

Share this post


Link to post
Share on other sites
Quote:
Original post by Nyarlath
A. First and most important, define it, no conditions. Virtual destructor means (for me and at least a few others) "I am a base class".


Erm, well, if you enjoy doing extra work in order to add useless overhead to your code in the case where the base class isn't intended to be used polymorphically, then be my guest. :) (This is also kind of at odds with your point B.)

Anyway, to the OP, I don't really understand how there can be any confusion when it's right there.

Quote:
Constructors and destructors are never undefined.


From context, he clearly meant "not explicitly defined". But an argument can be made that for every combination of types T^N that comprise a legal set of parameters for a constructor, every one not supported by the class' defined constructors is "undefined". ;)

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
Erm, well, if you enjoy doing extra work in order to add useless overhead to your code in the case where the base class isn't intended to be used polymorphically, then be my guest.

Erm, I don't call base class something that isn't intended to be used polymorphically. My fault, sorry.

Share this post


Link to post
Share on other sites
Thanks everyone for your replies!

Quote:
Original post by Zahlman
Anyway, to the OP, I don't really understand how there can be any confusion when it's right there.

That is the exact section I was referring to when I said it was a bit vague. That second-to-last paragraph, where it says "if your base class has a virtual destructor, then your destructor is automatically virtual". Seemed like a "duh" statement but still didn't address whether to create the virtual destructor in the first place.

Share this post


Link to post
Share on other sites
I think its refering to the destructor in the derived class; it doesn't need to be explicitly defined as virtual, its implied from the base class.

Share this post


Link to post
Share on other sites
Quote:
Original post by Guthur
I think its refering to the destructor in the derived class; it doesn't need to be explicitly defined as virtual, its implied from the base class.
However, if you use that derived class as a polymorphic base class itself, you might be better off explicitly defining the virtual destructor. I say this because several gcc/ld combinations seem to mess this case up, particularly across DLL boundaries.

Share this post


Link to post
Share on other sites
Quote:
Original post by Bregma
Quote:
Original post by iMalc
... and you delete the default constructor ...

How would one accomplish that neat trick?
Oh was my terminology a little off?
I mean the constructor that takes no arguments, the one that gets called when you don't provide any arguments. If you've written one of those you find it and press the delete key.
So what should I have called it?

Share this post


Link to post
Share on other sites
Quote:
Original post by iMalc
Oh was my terminology a little off?
I mean the constructor that takes no arguments, the one that gets called when you don't provide any arguments. If you've written one of those you find it and press the delete key.
So what should I have called it?


You are correct it is default constructor but i think what he means is you can delete it all you want, the compiler will still generate a default constructor so it can't be deleted per se :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Guthur
Quote:
Original post by iMalc
Oh was my terminology a little off?
I mean the constructor that takes no arguments, the one that gets called when you don't provide any arguments. If you've written one of those you find it and press the delete key.
So what should I have called it?


You are correct it is default constructor but i think what he means is you can delete it all you want, the compiler will still generate a default constructor so it can't be deleted per se :)
But that's just it, C++ doesn't generate the default constructor if you have defined other constructors.

Minimal example:
struct X {
X() {} // Try deleting this
X(int y) {}
};

X x;
Do people not know this, or was original post misread, or am I just not explaining it right?

Share this post


Link to post
Share on other sites
iMalc I stand corrected, it does indeed ask for a default to be defined if you have a non default constructor specified but use default constuction. Heres something else though, if you add the () it will compiler eg. A a();, but it will warn that no function of that prototype was found just a useless tibbit :)

[Edited by - Guthur on December 5, 2008 6:04:38 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by iMalc
Do people not know this, or was original post misread, or am I just not explaining it right?

All three, since evidently some people don't know that provide a contstructor, any constructor, will cause the automatically generated ones to not be automatically generated.

My confusion came because I didn't realize you meant that if you had already written a default constructor as well as other constructors, and you then delete the default constructor you had already written, then you will no longer have a default constructor. I gather this might be an artefact of using Visual Studio, like using a single unnamed void parameter instead of an empty parameter list.

The new C++09 language provides a way to explicitly disable automatically generated constructors (and operators). I thought maybe there was a technique in the existing language that did the same thing that I might be unaware of.

Share this post


Link to post
Share on other sites
Quote:
Original post by Bregma
All three, since evidently some people don't know that provide a contstructor, any constructor, will cause the automatically generated ones to not be automatically generated.

No, it's just the default constructor. The compiler will always generate the copy constructor unless you define it yourself even if you provide other constructors.

Share this post


Link to post
Share on other sites

This topic is 3294 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this