C
chsalvia
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.
But if the hash_set and hash_map class used private inheritance to
access the hash_table class, rather than composition/delegation, then
the hash_table class could have been written with a protected
constructor so that it couldn't be instantiated outside of a derived
class.
Plus, all the usual arguments against implementation inheritance
wouldn't really apply, since the hash_set and hash_map classes are not
designed to be inherited from anyway. (They have no virtual
destructor, like all STL-ish classes.)
Does anyone agree with me here? Or am I missing some more compelling
reasons to stick with composition/delegation in this case?
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.
But if the hash_set and hash_map class used private inheritance to
access the hash_table class, rather than composition/delegation, then
the hash_table class could have been written with a protected
constructor so that it couldn't be instantiated outside of a derived
class.
Plus, all the usual arguments against implementation inheritance
wouldn't really apply, since the hash_set and hash_map classes are not
designed to be inherited from anyway. (They have no virtual
destructor, like all STL-ish classes.)
Does anyone agree with me here? Or am I missing some more compelling
reasons to stick with composition/delegation in this case?