Inheriting a vector

K

Kai-Uwe Bux

Jerry said:
[ ... ]
That seems false: since the language allows public derivation of classes
without virtual destructor, public inheritance obviously does not
_promise_ that a derived class can be substituted for a base under _any_
circumstances.

You're takin the fact that something is standardized as meaning there
must be some circumstance under which it should be done, or is
meaningful, etc?

No, you are misconstruing my reasonging: The reference to the standard is
just to establish that there is no basis for your claim that public
inheritance makes the kind of promise you claim it makes.

This is completely independent of whether it can be a good idea to inherit
from classes with non-virtual destructors. That this is, indeed, the case
follows from examples like generic programming with policy classes or such
niceties as std::unary_function.

However, any of that does not mean that it is a good idea to inherit for
convenience from std::vector. But your reasoning was much wider in scope
than this particular case.

While I'm certainly not going to get into a long discussion over it,
this strikes me as fallacious reasoning. I guess if (for example) you
insist there's a good time to use gets, you can go ahead and do that.

I hope the remarks above make it clear that the reasoning runs a little
different. It should be clear, that the my reasoning, understood properly,
does not apply to gets.

I hope you'll forgive me if I pass. While I'll openly admit this isn't
_as_ dangerous as gets, it's still a bad idea -- there's simply no good
reason to do it.

So what about std::iterator and std::unary_function? What about policy
classes as featured in "Modern C++ Design"? There are plenty of good
reasons to publicly inherit from classes that do not have virtual
destructors. Your warning is good advice and firmly rooted in the paradigm
of OO design but does not extend far beyond. It does not apply in other
cases (like generic programming), where such inheritance indeed can be (and
often is) a good idea.

If you're deriving for the sake of convenience, and
don't want to allow (for example) pointers/references to your derived
class to be converted implicitly to pointers/references to the base
class, you have a choice of private or protected inheritance.

Again, consider std::binary_function and the likes of it. Here, private
inheritance is not an option for the intended use. In these cases, it is
just understood that you do not use std::binary_function<>* polymorphically
(and how/why would you: there are no virtual member functions to begin
with).


Best

Kai-Uwe Bux
 
K

Kai-Uwe Bux

Jerry said:
[ ... ]
Well put. There seem to be two schools of thought: one school emphasizes
the methods of tying the client down so that it cannot go astray; the
other school emphasizes the goal of designing a useful class and accepts
that undefined behavior may result from violating the preconditions of
the specified contract.

Pardon my being blunt, but this is barely short of complete nonsense.
Attempting to write your class in a way that it's reasonably safe isn't
tying the client down.

I think, I did not say that.

In the part you snipped, I cited the STL as an example for the second kind
of design: you get undefined behavior if you violate the contract. Do you
consider std::vector inherently unsafe because of operator[], which gives
you undefined behavior when you are out of bounds? I accept std::vector as
a class that is designed "reasonably safe": within typical idioms (loops
from begin() to end(), from 0 to size()), you get the behavior you expect,
and in cases that depart from there, you should use at().

However, I understand that one could argue that undefined behavior is to be
avoided in library classes, and from that point of view, std::vector is a
failed design. That is the difference between the two schools of though
that I see.
A design does not have to encourage its clients to shoot themselves in
the feet to be useful.

I think, I did not say that, either.


Best

Kai-Uwe Bux
 
B

Bo Persson

Jerry said:
[ ... ]
No, there's nothing undefined in destroying an object whose type is
derived from a type that does not have a virtual destructor. You
ONLY
get undefined behavior if you delete such an object through a
pointer to its base type.

Well, even I can't figure out what I wrote when you pull it apart
into
half-sentences, and reply to bits and pieces that were never
intended
to represent a complete thought. To clarify what I was trying to
say:

1) if you have code like this:

class base {}; // note lack of virtual dtor
class derived : public base {};

base *b = new derived;
// ...
delete b;

You'd get undefined behavior.

And that's about everything you get. If the base class has no virtual
functions, what is the use of this code anyway?

If you don't delete through a pointer to base, there *is* no problem.
and:

2) There's absolutely NOTHING you can do in 'derived' to prevent it
from being used in that fashion (or many similar ones that cause
similar problems).

There is generally nothing you can do to prevent abuse of your code,
except to document the intended use. "This class is not intended to be
used polymorphically!".


Bo Persson
 
P

Pete Becker

Jerry said:
Well, even I can't figure out what I wrote when you pull it apart into
half-sentences, and reply to bits and pieces that were never intended to
represent a complete thought.

Yup. Quoting everything from the beginning of your message and
responding to what that part said sure is misleading. So I'll adopt your
tactic, and snip the relevant quotes. Why confuse people with facts?

--

-- Pete

Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." For more information about this book, see
www.petebecker.com/tr1book.
 
G

Gavin Deane

toton said:
So the best thing I can do in my program ( I am the OP ! ) make a
comment ,"It is designed to use in that way, don't use it other way!" .

That's *exactly* what you do. Write the documentation. Explain how your
class is designed to be used. Test your code to be confident that, if
used that way, it works as expected. Then, anyone who uses your class
in a way not supported by your documentation and then complains that it
causes them a problem, doesn't have a leg to stand on.

Gavin Deane
 

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

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top