Necessity of pure virtual destructor?

V

Victor Bazarov

WittyGuy said:
I wonder the necessity of constructor and destructor in a Abstract
Class? Is it really needed?

If your class contains no data and produces no side effects when
constructed and/or destructed, then the default would be just fine.
If it does contain data, then you need to at least see how they are
constructed or disposed of, maybe you need to take control.

V
 
J

John Carson

Victor Bazarov said:
If your class contains no data and produces no side effects when
constructed and/or destructed, then the default would be just fine.
If it does contain data, then you need to at least see how they are
constructed or disposed of, maybe you need to take control.

?? As I understand it, the default destructor of the Abstract class will not
be virtual and hence derived class objects pointed to by a pointer to
Abstract will not have their destructor called when delete is called for the
Abstract pointer, e.g.,

class Abstract
{
public:
virtual void method()=0;
};

class Derived : public Abstract
{
virtual void method()
{}
~Derived()
{
// lots of stuff
std::cout << "Derived destructor\n";
}
};

int main()
{
Abstract * ptr = new Derived;
delete ptr;
}

You will observe that the destructor for Derived is never called. If,
however, you add

virtual ~Abstract(){}

to the definition of Abstract, then the Derived destructor is called.
 
C

Clark S. Cox III

If your class contains no data and produces no side effects when
constructed and/or destructed, then the default would be just fine.

Not true. If a class is abstract, then it, by definition, has virtual
functions, and will serve as a base class (if it is to be of any use).
In such a situation, it is usually very important to have a virtual
destructor. Whether that destructor is pure virtual or not is largely
irrelevant, but the compiler-provided one is *not* virtual, and is
therefore inadequate.
 
V

Victor Bazarov

John said:
If your class contains no data and produces no side effects when
constructed and/or destructed, then the default would be just fine.
If it does contain data, then you need to at least see how they are
constructed or disposed of, maybe you need to take control.


?? As I understand it, the default destructor of the Abstract class will
not be virtual and hence derived class objects pointed to by a pointer
to Abstract will not have their destructor called when delete is called
for the Abstract pointer, e.g.,
[...]

Yes, if polymorphic deletion is required, then the base class destructor
has to be declared virtual.

V
 
P

Pete Becker

Clark said:
Not true. If a class is abstract, then it, by definition, has virtual
functions, and will serve as a base class (if it is to be of any use).
In such a situation, it is usually very important to have a virtual
destructor. Whether that destructor is pure virtual or not is largely
irrelevant, but the compiler-provided one is *not* virtual, and is
therefore inadequate.

The compiler-generated destructor is only inadequate if you delete an
object of a derived type through a pointer to that base. Having or not
having virtual functions is irrelevant. Of course, if you want to define
an abstract class with no virtual functions, you do it by declaring the
destructor pure virtual.
 
B

ben

WittyGuy said:
Hi,
I wonder the necessity of constructor and destructor in a Abstract
Class? Is it really needed?

Constructor is optional.

Destructor is a must. Because you must allow user to delete the object from
the base.

Destructor must not be pure virtual. It just has to be defined. Use an empty
destructor if necessary.

ben



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
R

Razvan Cojocaru

That depends. There are two kinds of abstract classes in C++: classes
that don't have any state and all their methods are pure virtual
(similar to Java interfaces), and classes that have some state and/or
some of the behaviour already implemented (similar to Java abstract
classes - this is the kind of stuff you'd use, for example, to implement
the Template pattern).

In both cases, you _should_ add a virtual destructor. If you don't add a
virtual destructor, then deleting a derived class instance through a
pointer to a base class spells trouble. For more information on this,
you could check out Scott Meyers' books "Exceptional C++" and "More
Exceptional C++".

If your class is just an interface, then a constructor not only is _not_
needed, but it's useless. What would a constructor initialize, if the
class has no state?
If your class does have state information (data members) that needs to
be initialized prior to object usage, you will need to add a constructor.
Also, an abstract class might inherit from some other class that doesn't
have a default constructor, in which case you will have to initialize
the base class in an user-provided constructor.

The bottom line is: you _must_ use a constructor if your class has state
that needs to be explicitly initialized, and/or if a base class doesn't
have a default constructor. You _could_ use a constructor in several
other cases, but it's not strictly required.
And you must _always_ provide a virtual destructor if your class is
meant as a base class for some other class (which it surely is, since
it's abstract).


Hope it helps.

--
Razvan Cojocaru
KeyID: 1024D/04CA34DE

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
G

Gianluca Silvestri

WittyGuy said:
Hi,
I wonder the necessity of constructor and destructor in a Abstract
Class? Is it really needed?

The constructor is needed if the Abstract class contains any data member
which needs to be initialized. Usually there shouldn't be data members in
abstract classes bu sometimes...
A destructor is *definitely* needed, otherwise you'd get undefined behavior
deleting a derived object thru a pointer to base variable.

Ciao,
Gianuca


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
V

Victor Bazarov

Pete said:
[...] if you want to define
an abstract class with no virtual functions, you do it by declaring the
destructor pure virtual.

Isn't that statement self-contradicting? If you do declare the destructor
[pure] virtual, can you say that the class has "no virtual functions"? :)
 
F

Ferdi Smit

WittyGuy said:
Hi,
I wonder the necessity of constructor and destructor in a Abstract
Class? Is it really needed?
Yes! Otherwise what would happen if you called delete on a pointer with
static type base, which has dynamic type derived? Only base would be
destructed properly, and derived would leak stuff. A ctor can't be virtual
btw. Oh and remember that even a pure virtual dtor must have a body, this a
little oddity but perfectly logical.

--
Regards,

Ferdi Smit
smit xs4all nl



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
V

Victor Bazarov

Razvan said:
[...] For more information on this,
you could check out Scott Meyers' books "Exceptional C++" and "More
Exceptional C++".

That's "Effective C++" and "More Effective C++".
[...]
And you must _always_ provide a virtual destructor if your class is
meant as a base class for some other class (which it surely is, since
it's abstract).

Not if it the object of derived class is never deleted through a pointer
to the base class.

V
 
P

Pete Becker

Victor said:
Pete said:
[...] if you want to define an abstract class with no virtual
functions, you do it by declaring the destructor pure virtual.


Isn't that statement self-contradicting? If you do declare the destructor
[pure] virtual, can you say that the class has "no virtual functions"? :)

Sigh. To reestablish context, the assertion that I replied to was:
> If a class is abstract, then it, by definition, has virtual
functions, > and will serve as a base class (if it is to be of any use).
In such a > situation, it is usually very important to have a virtual
destructor.

My statement was that having virtual functions in itself has nothing to
do with needing a virtual destructor. You need a virtual destructor if
you're going to destroy an object of a derived type through a pointer to
that base.

I also made the observation that if a class has no virtual functions and
you want to make it abstract, you do so by declaring the destructor pure
virtual. AFTER you've done that, the class has one virtual function.
 
J

John Carson

Pete Becker said:
I also made the observation that if a class has no virtual functions
and you want to make it abstract, you do so by declaring the
destructor pure virtual. AFTER you've done that, the class has one
virtual function.

It is perhaps worth pointing out that this pure virtual function will need
an implementation in the base class.
 
M

msalters

WittyGuy said:
Hi,
I wonder the necessity of constructor and destructor in a Abstract
Class? Is it really needed?

Ctor: no - the compiler will create one for you.
Dtor: should be protected, virtual or both. The default is neither.

It is possible to write a correct program with a public non-virtual
dtor. This is simply because removing an access check from a correct
program levaes it correct. Removing 'protected' from a dtor is just
one case of this rule. However, without 'protected' you're not
protected against the delete-via-non-virtual-dtor bug.

HTH,
Michiel Salters


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
M

Martin Bonner

WittyGuy said:
Hi,
I wonder the necessity of constructor and destructor in a Abstract
Class? Is it really needed?

Absolutely. You can't create a class without a constructor or without
a destructor. (If you don't specify one, the compiler will do it for
you.)

I suspect that by "Abstract Class" you mean a class with just pure
virtual functions and no data members. Note that C++ allows base
classes with data members and real member functions.

I think you meant to ask about user specified constructors and
destructors. If so, there is no overriding need for a user specified
constructor (though of course, a particular class might benefit from
one - particularly if the class has data members which need
initializing).

In the case of a destructor I would be very surprised if you didn't
want to declare one. The problem is that the compiler generated
destructor will be public and non-virtual (assuming the class in
question has no bases with virtual destructors). This means there is
nothing to stop someone doing:
delete pAbstractClass;
where the actual object pointed at is of some derived type. If the
destructor is not virtual this is "undefined behaviour", which
basically means "bad things may happen".

There are two ways (I know of) to avoid the bad things. One is to
declare a virtual destructor (which avoids the bad things), the other
is to make the destructor protected (which makes the statement a
compilation error). Both of these methods require the destructor to be
declared.

There is less point making the destructor PURE virtual though (provided
at least one other function is pure virtual). A pure virtual function
a) has to be overriden by a derived class (but destructors have to be
overriden anyway); b) prevent the base class from being instantiated as
a specific object (but another pure virtual function will do that
anyway).

The other thing about pure virtual functions is that they don't need to
be implemented (although they can be). The exception is the destructor
- even if the destructor is pure virtual, it has to be implemented
(somewhere).

that means


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
P

Pete Becker

Ferdi said:
Yes! Otherwise what would happen if you called delete on a pointer with
static type base, which has dynamic type derived? Only base would be
destructed properly, and derived would leak stuff.

That's one possibility, but formally, the behavior is undefined.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
C

Clark S. Cox III

The compiler-generated destructor is only inadequate if you delete an
object of a derived type through a pointer to that base.

....and such a situation is exceedingly likely for most uses of abstract
classes. Hence my saying "usually", and not "always".
Having or not having virtual functions is irrelevant.

Every abstract class has virtual function by definition.
Of course, if you want to define an abstract class with no virtual
functions, you do it by declaring the destructor pure virtual.

So, to define an abstract class with no virtual functions ... you add a
virtual function?
 
P

Pete Becker

Clark said:
So, to define an abstract class with no virtual functions ... you add a
virtual function?

Yes. If you have a class with no virtual functions and you want it to be
an abstract class you make its destructor pure virtual.
 
H

Howard

ben said:
Constructor is optional.

Destructor is a must. Because you must allow user to delete the object
from
the base.

I take it you mean "...to delete a derived-class object via a pointer to a
base-class object"?

That's what a _virtual_ destructor gives you the aility to do. It's not a
requirement if you don't need to do that, and it needs to be declared
virtual in order to accomplish that.

-Howard




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top