Inheritance of two or more ROOT classes

Dear ROOTers,

Could you advise me please how to properly construct a class based on two
ROOT classes namely TVector3 and TNamed that in turn are based on the class
TObject. The problem is if I merely inherit these classes as follows

//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Contents of a file MyClass.h
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#ifndef MyClass_h
#define MyClass_h

#ifndef ROOT_TVector3
#include "TVector3.h"
#endif

#ifndef ROOT_TNamed
#include "TNamed.h"
#endif

class MyClass : public TVector3, public TNamed
{
 public:
  MyClass();
  virtual ~MyClass();

  ClassDef(MyClass,1)
};

#endif // End of the definition "MyClass_h"
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Contents of a file MyClass.cxx
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#include "MyClass.h"

ClassImp(MyClass)

MyClass::MyClass() : TVector3(), TNamed()
{
  cout << "Invoking MyClass." << endl;
}

MyClass::~MyClass()
{
  cout << "Invoking ~MyClass." << endl;
}
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

then I’ve got a multiple ambiguous inheritance of the class TObject. This
kind of problem would be overcome successfully if the class TObject were
declared as a virtual base class inside the classes TVector3 and TNamed,
i.e. class TVector3 : virtual public TObject {…};
class TNamed : virtual public TObject {…};

Is there any other way to overcome this problem? I would appreciate any
help. Thank you in advance,

Cheers,
Alexander

Comrades,

Why don’t we inherit TObject as a virtual base class?
For example:

class TVector3 : virtual public TObject { ... };

instead of

class TVector3 : public TObject { ... };

Probably I’m missing something but that would allow us
to inherit that kind of classes (TVector3 and etc) many times,
and overcome multiple ambiguous inheritance of TObject. Then
the above mentioned example would be applicable. Sorry if I’m
suggesting something stupid…

Cheers,
Alexander

Hi,

This is something we could consider. However there are several issues, including backward compatibility and CINT support that we need to investigate very very carefully before making such a change.

On the other hand, what is the purpose of inheriting both from TVector3? Is your class really a ‘named’ TVector3? In a lot of situation the inheritance relationship is not the best approach and using composition is better.

Cheers,
Philippe.

Hi Philippe,

All I would want to do is to construct a class having two base classes
TVector3 and TNamed. It would be possible if their base class TObject
were declared as virtual. I thought it would be aslo good to implement
the same thing for all classes inheriting directly from the TObject.
I understand that this is not so easy especially taking into account
backward compatibility. Unfortunately I’m a beginer in ROOT and C++,
and not confident to perform this kind of work for now.

Sorry for my misunderstanding but what do you mean by “composition”?
Do you suggest to include these classes in a constructor as arguments?

Cheers,
Alexander

Hi,

What I meant by composition is:

[code]class MyClass : public TNamed
{
TVector3 fVec;
public:
MyClass();
const TVector3& GetVector() { return fVec; }
virtual ~MyClass();

ClassDef(MyClass,1)
};[/code]

Cheers,
Philippe.

Hi Philippe,

OK, I’ve got it.

At this point I’d like to ask you about a similar problem. In my experiment
I have a framework in which I have to convert a ntuple file into a root file.
After this, I create skeleton files corresponding to each ntuple tree
(I’ve two ones). Here I’d decided to construct a loader class having the
two above mentioned skeleton classes as base ones. But in this way I need
to make a compilation for each root file (since a skeleton file is not
dynamic). Is ther any other way to overcome this problem? I’m not sure
I can read “blindly” contents of a root file by using TTree and
TTreePlayer’s functions (it seems to me that would be slowly
implementation). Am I right?

Thank you for help,
Cheers,
Alexander

[quote]it seems to me that would be slowly implementation
[/quote]That’s really depend on the cases.

Why? What do you could a skeleton? In which way is it not dynamic?

Philippe.

Hi Philippe,

Yes, I was wrong. One only may imagine the following case: let’s suppose
we have a variable responsible for number of hits in a calorimeter (Ncalo)
and an array containing calorimeter’s amplitudes (Acalo[ ]). The size of
last one is statically defined during a ntuple defintion. So we can use
permanently a definition of skeleton class inside a descendant class
(the loader class) unless the ntuple defintion has been changed. Once
it happened, we need to make a reconvertation. Yes, this is OK somehow.

Cheers,
Alexander