 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Gabriel Zachmann Guest
|
Posted: Mon Dec 15, 2003 10:19 am Post subject: trait or multiple inheritance? |
|
|
Is there a simple rule that could be used as a guideline
when to use traits and when to use multiple inheritance (where all but one
base class would be abstract, of course).
Thanks a lot in advance,
Gabriel.
--
/-------------------------------------------------------------------------
| Quote: | zach (AT) cs (DOT) uni-bonn.de __@/' [email]Gabriel.Zachmann (AT) gmx (DOT) net[/email] |
web.informatik.uni-bonn.de/~zach __@/' www.gabrielzachmann.org |
-------------------------------------------------------------------------/ |
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
stelios xanthakis Guest
|
Posted: Mon Dec 15, 2003 9:47 pm Post subject: Re: trait or multiple inheritance? |
|
|
Gabriel Zachmann <zach (AT) cs (DOT) uni-bonn.de> wrote
| Quote: | Is there a simple rule that could be used as a guideline
when to use traits and when to use multiple inheritance (where all but one
base class would be abstract, of course).
Thanks a lot in advance,
Gabriel.
|
This is answered in the lwc tutorial very clearly.
Quoting:``Multiple inheritance makes sense when the parent
objects have common members. Unless virtual inheritance, the
only possible common member is 'this'. In other words, if
you redefine virtual member functions of 'A' to use members
of 'B' **AND** you redefine virtual member functions of 'B'
to use members of 'A'. You don't need it unless you really
know that you need it.''
So use traits if both traits and multiple inheritance can
solve the problem.
stelios
http://students.ceid.upatras.gr/~sxanth/lwc/index.html
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dietmar Kuehl Guest
|
Posted: Mon Dec 15, 2003 10:10 pm Post subject: Re: trait or multiple inheritance? |
|
|
Gabriel Zachmann <zach (AT) cs (DOT) uni-bonn.de> wrote:
| Quote: | Is there a simple rule that could be used as a guideline
when to use traits and when to use multiple inheritance (where all but one
base class would be abstract, of course).
|
I would claim that inheritance (note the deliberate absence of "multiple")
should only be used when runtime polymorphism is required. Due to technical
reasons sometimes (single) base classes are needed as a decoupling tool to
save programmer sanity, though. That essentially results in the simple rule:
Use inheritance when it is necessary and avoid it otherwise.
--
<mailto:dietmar_kuehl (AT) yahoo (DOT) com> <http://www.dietmar-kuehl.de/>
Phaidros eaSE - Easy Software Engineering: <http://www.phaidros.com/>
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gabriel Zachmann Guest
|
Posted: Wed Dec 17, 2003 9:57 am Post subject: Re: trait or multiple inheritance? |
|
|
Thanks for your response (and that of Stelios!)
| Quote: | I would claim that inheritance (note the deliberate absence of "multiple")
should only be used when runtime polymorphism is required. Due to technical
reasons sometimes (single) base classes are needed as a decoupling tool to
save programmer sanity, though. That essentially results in the simple rule:
Use inheritance when it is necessary and avoid it otherwise.
|
I believe that rule is a good one in general.
But when implementing (pure) interfaces, I would like to know
*why* traits are to be preferred over multiple inheritance.
TIA,
Gabriel.
--
/-------------------------------------------------------------------------
| Quote: | zach (AT) cs (DOT) uni-bonn.de __@/' [email]Gabriel.Zachmann (AT) gmx (DOT) net[/email] |
web.informatik.uni-bonn.de/~zach __@/' www.gabrielzachmann.org |
-------------------------------------------------------------------------/ |
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
David Abrahams Guest
|
Posted: Wed Dec 17, 2003 7:11 pm Post subject: Re: trait or multiple inheritance? |
|
|
Gabriel Zachmann <zach (AT) cs (DOT) uni-bonn.de> writes:
| Quote: | Thanks for your response (and that of Stelios!)
I would claim that inheritance (note the deliberate absence of "multiple")
should only be used when runtime polymorphism is required. Due to technical
reasons sometimes (single) base classes are needed as a decoupling tool to
save programmer sanity, though. That essentially results in the simple rule:
Use inheritance when it is necessary and avoid it otherwise.
I believe that rule is a good one in general.
But when implementing (pure) interfaces, I would like to know
*why* traits are to be preferred over multiple inheritance.
|
The key feature of traits is that they're non-intrusive. You can
associate types and operations with other types, without modifying the
definitions of those other types. If someone hands you a type from a
3rd party library, or even a built-in type, you can make it fit some
interface if that interface is defined entirely in terms of traits.
To use inheritance, you have to modify the definition of the class.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Thomas Hansen Guest
|
Posted: Wed Dec 17, 2003 11:24 pm Post subject: Re: trait or multiple inheritance? |
|
|
On 15 Dec 2003 17:10:08 -0500, there came a drop of sanity from
[email]dietmar_kuehl (AT) yahoo (DOT) com[/email] (Dietmar Kuehl) containing:
| Quote: | Gabriel Zachmann <zach (AT) cs (DOT) uni-bonn.de> wrote:
Is there a simple rule that could be used as a guideline
when to use traits and when to use multiple inheritance (where all but one
base class would be abstract, of course).
I would claim that inheritance (note the deliberate absence of "multiple")
should only be used when runtime polymorphism is required. Due to technical
reasons sometimes (single) base classes are needed as a decoupling tool to
save programmer sanity, though. That essentially results in the simple rule:
Use inheritance when it is necessary and avoid it otherwise.
|
What about policy based design?
Many times you need multiple inheritance where you don't really need
the polymorphisme...
E.g.
template<class T, class DTORPolicy>
class smart_ptr : public typename DTORPolicy
{
T* itsObject;
~smart_ptr
{
// Impl. in DTORPolicy class
destroy();
}
};
Also you have some places where you will do "quasi" Aspect Oriented
Programming using multiple inheritance where you don't really need the
polymorphism but still need to apply aspects to classes with multiple
inheritance!
Look at e.g. SmartWin for a good example of Multiple Inheritance and
AOP...
(SmartWin need polymorphisme though too...! ;)
--
http://smartwin.sourceforge.net THE template based Windows API GUI Library
My email:
"john.johnson (AT) theJohnsons (DOT) com"
* Replace "john" with "thomas", replace "johnson" with "hansen", replace "theJohnsons" with "adramatch"
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dietmar Kuehl Guest
|
Posted: Thu Dec 18, 2003 4:43 pm Post subject: Re: trait or multiple inheritance? |
|
|
Thomas Hansen <syilei (AT) yahoo (DOT) com> wrote:
| Quote: | On 15 Dec 2003 17:10:08 -0500, there came a drop of sanity from
[email]dietmar_kuehl (AT) yahoo (DOT) com[/email] (Dietmar Kuehl) containing:
I would claim that inheritance (note the deliberate absence of "multiple")
should only be used when runtime polymorphism is required. Due to technical
reasons sometimes (single) base classes are needed as a decoupling tool to
save programmer sanity, though. That essentially results in the simple rule:
Use inheritance when it is necessary and avoid it otherwise.
What about policy based design?
|
You can do policy based design without using base classes. Also, I don't
really mind using private base classes if technical reasons make the use
of inheritance favourable. ... and my assertion was indeed somewhat too
strong: the tricky part about simple guidelines is that they miss many
aspects because the reality is more complex.
| Quote: | Many times you need multiple inheritance where you don't really need
the polymorphisme...
E.g.
template<class T, class DTORPolicy
class smart_ptr : public typename DTORPolicy
{
T* itsObject;
~smart_ptr
{
// Impl. in DTORPolicy class
destroy();
}
};
|
What is wrong with this?
template
class smart_ptr
{
T*itsObject;
public:
~smart_ptr() { DTORPolicy::destroy(itsObject); }
};
It actually has the advantage of resolving a potential name conflict
between multiple 'destroy()' functions in different policies.
| Quote: | Also you have some places where you will do "quasi" Aspect Oriented
Programming using multiple inheritance where you don't really need the
polymorphism but still need to apply aspects to classes with multiple
inheritance!
|
You can do Aspect Oriented Programming without multiple inheritance by
using appropriate public members (before people complain about public
members: public base classes without any runtime polymorphism are
effectively anonymous public members). The only drawback of using members
rather than base classes, depending on your needs a major one though, is
that you cannot cast one aspect into another one or get the enclosing
object of the aspect. Using multiple inheritance allows this readily but
then it is actually some form of dynamic polymorphism.
--
<mailto:dietmar_kuehl (AT) yahoo (DOT) com> <http://www.dietmar-kuehl.de/>
Phaidros eaSE - Easy Software Engineering: <http://www.phaidros.com/>
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
galathaea Guest
|
Posted: Fri Dec 19, 2003 7:52 am Post subject: Re: trait or multiple inheritance? |
|
|
Gabriel Zachmann <zach (AT) cs (DOT) uni-bonn.de> wrote
| Quote: | Is there a simple rule that could be used as a guideline
when to use traits and when to use multiple inheritance (where all but one
base class would be abstract, of course).
Thanks a lot in advance,
Gabriel.
|
I think there are very important differences that classify the cases.
And I believe that classification also presents a fairly complete use
case decomposition that I find useful.
Multiple inheritance is an edge set in the inheritance digraph which
cause it to fail to be a tree. It is useful if the bases are
lightweight objects with a manageable amount of functions and state
attached, but late in an inheritance hierachy, it can be a sign of
bloat. Much of the objects more complicated functionality may not
ever be used. I like to keep my objects interactions as simple as
possible, because I consider the rest of the stuff which I do not need
background noise. I think it just complicates the rest of the mental
mapping a programmer must maintain to know and build areas of
applications.
But I apply a criteria to inheritance in general that it looks like
you are already thinking about as well. I (try) to use inheritance
mostly when its specifically for the need of dynamically bound
polymorphism through abstract interfaces. Inheritance for me tends to
stay fairly shallow. That applies to mi as well. So I (almost) only
look at multiple inheritance when I need an object that can passed
around in two or more janus-like interface forms which will vary
dynamically, and so far that has been pretty rare for me. (The almost
appies to the empty base optimisation and policies.)
But when the functions or state of an object vary due to static,
architectural type decisions or are being constructed as local "tool
objects" as in library components, template tricks offer much nicer
capabilities. And I usually choose to start with traits because they
are really quite capable in minimising interface bloat and controling
complexity.
Mechanisms such as the completely statically existing typedefs are
available to pass typename information around. And typename
information can be a rather strong source of coupling in code, as it
is placed at all object instancing. When one wants instancing an
object to be able to vary that easily, for some genericity and
reusability, passing a traits type as a template parameter is very
easy. You want to come and change that, you go back to the instance
and switch template parameters and code up the new variation.
Using multiple inheritance in a similar way as traits (ie. in
statically varying constructional purposes) brings along the baggage
of type conversion knowledge when its not needed. You have the
baggage of ctor / dtor chains (which is still conceptual "as-if"
baggage if optimised away on abstract interfaces). And usually, if
you have some functions lying around that are looking to be passed
various faces in one object whose type can be known statically, those
faces do not need the inheritance relationship. Particularly with
concept checking, parametrised algorithmics can be quite safe, with
static reporting of wide ranges of errors including the failure to
define what would be "the pure virtual", or expected interface
function.
So usually when I need to begin refactoring an object to add points of
static variation, I will start with traits. Usually being able to
vary typenames and function / execution is all I need. However, and
this where I come back to the earlier exception, sometimes the static
variation needs state and that state cannot be static across all
instances. In those cases, parametrised inheritance comes in handy,
even or especially in parametrised multiple inheritance, because the
empty base optimisation prevents unnecessary size bloat. In those
case where I have had to add state variation points, refactoring to
policies has turned out to keep coupling quite low. Except, policies
use of multiple inheritance is quite different than your base
interface classes. Policies have state and work with it.
Thats basically the breakdown I use. I start with as flat a type
space as possible, with hierarchies mostly interface-derived two layer
relationships for polymorphic purposes and a lot of loose types and
free algorithms. When the code needs to evolve through another
refactoring and growth, those variation point changes which will be
statically decided are usually functional or type association related,
so traits are often my first choice. For those cases where state will
vary, parametrised multiple inheritance is my choice.
I believe these guidelines I follow are not that different than the
way the standard library is evolving or is found in the stuff coming
out of boost, and I believe their fairly robust rules of thumb. The
rationale for my choice is mostly based upon reducing the amount of
work I need to do when the system goes through an iteration, because
it makes my job a whole lot more enjoyable.
=)
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
** galathaea: prankster, fablist, magician, liar **
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|