Howard said:
Actually, this is one of the best examples of what is *not* a good example
for inheritance.
It's the classic "A's can X, B is an A, B can't X" trap.
All birds gotta fly,
Ostrich is a bird,
Ostrich can't fly.
All rectangles can have two different side lengths,
Square is a rectangle,
Square cannot have two different side lengths.
I believe Meyers covers this exact case in one of his books.
It's also covered fairly well in "C++ FAQs (2nd Edition)"
by Marshall P. Cline, Greg A. Lomow, and Mike Girou.
Basically, you have to give up one (or more)
of the three lines of the trap. And you detect the trap
in advance by insisting that derived classes can substitute
for the parent class. So, ask "Can I use a square every
time I need a rectangle?" If, in the context of the case,
the answer is no, then it is likely to be a bad choice for
public derivation.
Or, "Can I use an ostrich every time a bird is wanted?"
The context may say no, or it may say yes. For example,
when ostrich is required to fly, you could adjust things
so that somebody buys an airline ticket for the bird.
Or you could redefine "fly" in some other way such that
ostriches can fly. Or you could change the middle line,
such that "bird" and "ostrich" each derived from some
other entity, say "protoBird" that did not have any
characteristics about flying. Or you could relax the
requirement that birds must fly, say, by allowing the
call to "Fly" to throw an exception. In any case, you
have to drop one or more lines from the three of the trap.
But get the FAQ book as the coverage there is much better
than I've managed here.
Socks