Re: Composition versus Implementation Inheritance
On Jul 28, 3:39 pm, Erik Wikstr=F6m <Erik-wikst...@telia.com> wrote:
On 2007-07-28 08:21, chsal...@gmail.com wrote:
Most modern sources on C++ design say that composition is usually
preferable to implementation inheritance because inheritance tends to
lead to problems down the road unless it follows a strict model
allowing substitution, where each derived class has an "is-a"
relationship with the base class.
I was wondering, however, if implementation inheritance (private
inheritance) might be a better idea in some cases. Consider the SGI C+
+ extension implementation of hash_set and hash_map. Both hash_set
and hash_map use composition to reuse code from an internal class.
They each have an internal hash_table class, which implements the
basic functions of a hash table. The hash_set and hash_map class use
delegation to access the functionality of the internal hash_table
class. Google's sparse hash map/hash set also uses the same design
scheme.
This is a nice clean design, except one thing about it really bothers
me. There's nothing preventing someone from instantiating an instance
of the internal hash_table class somewhere else. Unlike an abstract
base class, or a base class with a protected constructor, the internal
hash_table "base" class can be instantiated anywhere, even though this
would be useless.
So what if they can be instantiated, what harm would it do. As you say
it will probably be useless but you can't know the needs of every
developer out there.
More to the point: if it's really useless, you don't have to do
anything to prevent it, since no one will do it.
In this case, there might be a case to argue that the base class
isn't adequately documented for use by others. As far as I can
tell, there's absolutely no guarantee that it will even be
present in the next release, or have the same interface if it
is. But again, I'd say that this is the user's problem. If one
is stupid enough to use some undocumented interface, then one
deserves whatever happens. (And realistically, there are many
cases where you cannot really avoid it.)
I think this is kind of making it impossible to
inherit from a class, I can't see any need for it. All it would
accomplish would be to prevent possible ways of implementation.
Since you can't anticipate all the requirements that might be
placed on your application in the future you should try to not
artificially limit the extensibility of your code (unless it
makes it easier to satisfy the current requirement).
You're code is really only extensible in ways you've planned for
and documented. But let's face it, only a fool would try to use
something that wasn't planned for and documented. (It's not
as though you might accidentally use it, as a result of a typo.)
--
James Kanze (Gabi Software) email: james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34