NonCopyable

T

Tim Clacy

Having come across a few NonCopyable classes, I just wondered why they don't
have virtual destructors. Doesn't this limit there usefulness? In fact,
there seem a whole bunch of generic classes in Boost, for instance, that
don't have virtual destructors but that do expose public constructors.
Aren't these a recipe for disaster?

Boost has an 'abstract' class that simply defines a virtual destructor; is
the idea that the programmer tags this on the end of the inheritence list if
they want to be able to 'delete' through a base class pointer?
 
J

Jeff Schwab

Tim said:
Having come across a few NonCopyable classes, I just wondered why they don't
have virtual destructors. Doesn't this limit there usefulness? In fact,
there seem a whole bunch of generic classes in Boost, for instance, that
don't have virtual destructors but that do expose public constructors.
Aren't these a recipe for disaster?

No, why? There's only a problem if someone tries to delete a derived
class through a pointer to a base without a virtual destructor. This
isn't always likely to happen, and the absence of a virtual destructor
pretty much says "don't do that."
Boost has an 'abstract' class that simply defines a virtual destructor; is
the idea that the programmer tags this on the end of the inheritence list if
they want to be able to 'delete' through a base class pointer?

No idea, but I like your interpretation. :)
 
T

tom_usenet

Having come across a few NonCopyable classes, I just wondered why they don't
have virtual destructors. Doesn't this limit there usefulness? In fact,
there seem a whole bunch of generic classes in Boost, for instance, that
don't have virtual destructors but that do expose public constructors.
Aren't these a recipe for disaster?

Generally you inherit privately from NonCopyable classes (like
boost::noncopyable), so there is no likelihood of problems. There is
also no reason to ever have a noncopyable*. How were you envisioning
this disaster occurring? Adding a virtual destructor to
boost::noncopyable would be a terrible thing to do - lots of classes
which don't have virtual functions use noncopyable, and these would
suddenly all gain an unnecessary vtable (and associated RTTI, etc.).

Also, could you give another example of these generic classes that
might have a problem? I suspect that you're seeing danger where there
is none, or only some through serious misuse (such as subclassing a
class that shouldn't be subclassed).
Boost has an 'abstract' class that simply defines a virtual destructor; is
the idea that the programmer tags this on the end of the inheritence list if
they want to be able to 'delete' through a base class pointer?

Where is this class? I found a class deep in some test header that was
called "abstract", but no others, and no end user ones.

Tom
 
T

Tim Clacy

Jeff said:
No, why? There's only a problem if someone tries to delete a derived
class through a pointer to a base without a virtual destructor. This
isn't always likely to happen, and the absence of a virtual destructor
pretty much says "don't do that."

Jeff,

I admire you're faith in programmers but, to me, "This isn't always likely
to happen" means it definately will happen and when it does happen you have,
at best, a memory leak :)
 
T

Tim Clacy

tom_usenet said:
Generally you inherit privately from NonCopyable classes (like
boost::noncopyable), so there is no likelihood of problems. There is
also no reason to ever have a noncopyable*. How were you envisioning
this disaster occurring? Adding a virtual destructor to
boost::noncopyable would be a terrible thing to do - lots of classes
which don't have virtual functions use noncopyable, and these would
suddenly all gain an unnecessary vtable (and associated RTTI, etc.).

Fair enough. "Just out of curiousity", said the cat, what would you do if
you wanted to define a class that should be non-copyable but which could be
inherited from?
Also, could you give another example of these generic classes that
might have a problem? I suspect that you're seeing danger where there
is none, or only some through serious misuse (such as subclassing a
class that shouldn't be subclassed).


Where is this class? I found a class deep in some test header that was
called "abstract", but no others, and no end user ones.

Tom

You're absolutely right; it's in data.hpp, which is underneath the
meta-programming root

class abstract { virtual ~abstract() = 0; };
 
I

Ivan Vecerina

Tim Clacy said:
Having come across a few NonCopyable classes, I just wondered why they don't
have virtual destructors. Doesn't this limit there usefulness? In fact,
there seem a whole bunch of generic classes in Boost, for instance, that
don't have virtual destructors but that do expose public constructors.
Aren't these a recipe for disaster?

Not if you *privately* derive from the base class, which should be
the case when deriving from NonCopyable.

Empty base classes are used at times, maybe especially in designs
involving templates, to import a set of declarations in a subclass.
This could be dangerous if public inheritance is used and the
subclass can be instantiated. In practice, however, I do not think
this is a common problem.

Boost has an 'abstract' class that simply defines a virtual destructor; is
the idea that the programmer tags this on the end of the inheritence list
if they want to be able to 'delete' through a base class pointer?

A class that declares a pure virtual destructor does not force
its subclasses to be abstract, so such a class would appear to
be redundant as a tag for abstract classes. Furthermore, a memory
overhead of 1 pointer per instance of the derived class may be incurred.

I would rather derive the top-most base class from 'abstract'.
This could be useful in OO designs to allow classes to share a
common disposal mechanism.

Regards,
Ivan
 
T

Tim Clacy

Tim said:
Fair enough. "Just out of curiousity", said the cat, what would you
do if you wanted to define a class that should be non-copyable but
which could be inherited from?

Hmm, before someone else points out what an absurd question this is, I would
like to do so.
 
J

Jeff Schwab

Tim said:
Jeff,

I admire you're faith in programmers but, to me, "This isn't always likely
to happen" means it definately will happen and when it does happen you have,
at best, a memory leak :)

It's not faith, it's respect. If you think you can make your libraries
abuse-proof, then /I/ admire /your/ faith.
 
I

Ivan Vecerina

I happen to see legitimate code that new-s and delete-s instances of
classes that do not have a virtual destructor.
So the absence of a virtual destructor doesn't exclude calling delete.

This is not a theoretical issue, but a real opportunity
for undefined behavior.
( though I agree that this is not a real issue for
'stub' classes such as NonCopyable ).
It's not faith, it's respect. If you think you can make your libraries
abuse-proof, then /I/ admire /your/ faith.

Inapropriate deletion through a base class pointer is a good example
of accidental misuse, which IMHO every decent C++ programmer should
seek to prevent.


Cheers,
 
T

tom_usenet

You're absolutely right; it's in data.hpp, which is underneath the
meta-programming root

class abstract { virtual ~abstract() = 0; };

Yup, that's the one I saw.
Boost has an 'abstract' class that simply defines a virtual destructor; is
the idea that the programmer tags this on the end of the inheritence list if
they want to be able to 'delete' through a base class pointer?

I don't think it's really useful for anything much, to be honest.
Boost seems to be using it as a metaprogramming tag to represent the
set of abstract classes.

Adding a tag class to use as a base class for inheritable classes
introduces unnecessary overhead.

Tom
 

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
474,169
Messages
2,570,919
Members
47,460
Latest member
eibafima

Latest Threads

Top