Re: multiple inheritance and TObject

From: Axel Naumann <axel-naumann_at_gmx.de>
Date: Sat, 05 Feb 2005 00:57:39 -0600


Salut Sebastien,

it won't work like that. The problem is shown in this "diamond" graph:

              TObject
                 |
       --------------------
      |                    |
      |                   ...
     TLV                 TObjArray
[has TObject]        [ has TObject ]
      |                    |
       --------------------
                 |
            AnotherClass
        [has TLV, TObjArray]



The compiler can't know which TObject's methods to use, e.g. calling AnotherClass::SetBit(), as there are two TObjects, one being the base of TLV, and the other being the base of TObjArray. And it can't know which path to take when you do

   AnotherClass my;
   TObject* &my;

You'll have to make the TObject bases virtual ("class TObjArray: virtual public TObject"), which marks one of the TObjects as being identical to the other - there will be only one base-TObject for AnotherClass. Now, that would mean changing root code; it's probably not what you want.

And you'll also have to implement "switch" methods in AnotherClass for virtual methods that TObject has, and that are implemented in AnotherClass's base classes, defining which method to call. GetName is one an example: it's implemented in both TObject and again in TCollection. When calling AnotherClass::Print - which one should be called? This is what a "switch" method does:

void AntherClass::Print(...) {

   TCollection::Print(...);
}

That's the generic way of dealing with multiple inheritance from the same base class - and it's only a few of the issues[1]. I have no idea how many compilers will actually understand that, and Cint's poking-around-in-members probably won't help either - assuming Cint itself can handle it (I don't know that either).

So, after one page of email - do yourself a favor and make one of your base classes a member. You could wrap its methods, and forward them to the member, which makes it look like it's a base class. Of course you will not be able to upcast your object to both a TObjArray _and_ a TLV... O, and no warranty on anything I said here - read the c++ ISO standard (ch 10.1 ff) if you want know what is supposed to work ;-)

Good luck!
Axel.

[1]: Bruce Eckelt has written a reasonably short summary of this "MI" problem in his electronic book "Thinking C++, Volume 2": http://mindview.net/Books/TICPP/ThinkingInCPP2e.html

Sebastien Greder wrote:
> Hello,

> 

> I would like to know if there is a way to handle multiple
> inheritance with ROOT ; i.e avoid the warning message
> one gets from rootcint having troubles to handle this
> situation.
> My inheritance tree is as follow :
> 

> TLorentzVector
> |
> MyCLass TObjArray (or TSeqColl ..)
> | |
> -----|------
> |
> AnotherClass
>
> thanks,
> 

> sebastien
>
> 

> ---------------------------------------------------------------------
> | Dr. Sebastien GREDER tel : +33 (0)3 88 10 63 54 |
> | D0 Strasbourg, |
> | Institut de Recherches Subatomiques fax : +33 (0)3 88 10 62 34 |
> | 23, rue du loess - BP 28 secr : +33 (0)3 88 10 66 40 |
> | F-67037- STRASBOURG cedex 2 e-mail : greder_at_in2p3.fr, |
> | greder_at_fnal.gov |
> ---------------------------------------------------------------------
> > > >
Received on Sat Feb 05 2005 - 07:57:45 MET

This archive was generated by hypermail 2.2.0 : Tue Jan 02 2007 - 14:45:04 MET