Dictionaries and Multiple Inheritances

Hi All,

I am having a strange problem with a class with multiple inheritances. (Not a diamond Inheritance issue.)
For reference I am using root v5.34/18. ScientificLinux6 with gcc version 4.4.6.

I have two base classes

[code]class AbstractBase {

public:
virtual void MyMethod();

virtual void AnotherMethod() = 0;
ClassDef(AbstractBase,1);
};
class Data : public TObject {

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

AbstractBase is abstract but the Data class is not. I have another class on which I want to do some analysis

class myObject : public AbstractBase, public Data {
...
public:
   void MyMethod();
   void AnotherMethod();

   ClassDef(myObject,1);
};

myObject is not abstract.

Now, I have a couple of questions:
[ul]

  1. First, when I write myObject to a ROOT file, will the data members of AbstractBase also be written? Or should I avoid putting data members into AbstractBase?

  2. It seems that rootcint will fail if I inherit from Data before AbstractBase. I do not understand why.

[quote]Error: abstract class object ‘myObject second’ declared /usr/local/src/root_v5.34.18/cint/cint/lib/prec_stl/utility:19:
Error: abstract class object ‘myObject second’ declared /usr/local/src/root_v5.34.18/cint/cint/lib/prec_stl/utility:19:
Warning: Error occurred during reading source files
Warning: Error occurred during dictionary source generation[/quote]
If, however, I make AbstractBase not abstract by commenting out the purely virtual functions, the compilation works, but I run into problem 3.

  1. If I inherit AbstractBase first, the compilation works. But when I try to use the class in the interpreter I get the error:

It does not tell me which base class. But for reference MyMethod does access protected functions in the Data class.
[/ul]

The LinkDef.h file includes the lines

#pragma link C++ class AbstractBase+;
#pragma link C++ class Data+;
#pragma link C++ class myObject+;

Everything works fine if I just combine the AbstractBase class into the myObject class as a single class that inherits from Data. (But later, I would like to have several classes that inherit from different data classes that can all be downcast to the AbstractBase class.)

I have the feeling that the problem is originating with the fact that I am inheriting from two classes.

I have tried making AbstractBase inherit from TObject and making both inheritances virtual to solve the diamond problem. But this created problems with my IO.

Anyone have experiences with this?

Cheers,
–Jon

[quote]1. First, when I write myObject to a ROOT file, will the data members of AbstractBase also be written? Or should I avoid putting data members into AbstractBase? [/quote]Yes.

[quote]2. It seems that rootcint will fail if I inherit from Data before AbstractBase. I do not understand why…
3. If I inherit AbstractBase first, the compilation works. But when I try to use the class in the interpreter I get the error:[/quote]seems to be CINT deficiencies. Can you try with v6.00/02 which should solve these problems?

Cheers,
Philippe.

Hi Philippe,

I’m currently running gcc 4.4.6 and it appears that root v6.00/02 requires gcc >= 4.8 (presumably for c++11 support?). I think trying to install this at this point may be verging on reinventing the wheel.

Any other possibilities or work arounds in the mean time?

Cheers,
–Jon

Hi Jon,

I failed to reproduce any of the error you mentioned. I tried with the file:[code]class AbstractBase {
public:
virtual void MyMethod() {};

virtual void AnotherMethod() = 0;
virtual ~AbstractBase() {};
ClassDef(AbstractBase,1);
};
class Data : public TObject {
ClassDef(Data,1);
};

class myObject : public AbstractBase, public Data {
//class myObject : public Data, public AbstractBase {
public:
void MyMethod() {};
void AnotherMethod() {};

ClassDef(myObject,1);
};

#include

#ifdef MAKECINT
#pragma link C++ class AbstractBase+;
#pragma link C++ class Data+;
#pragma link C++ class myObject+;
#pragma link C++ class pair<int,myObject>+;
#pragma link C++ class map<int,myObject>+;
#endif
[/code]

which compiles fine (with ACLiC for example) and with the alternate order of inheritance the execution seems to work.

Can you provide a complete running / failing example ?

Cheers,
Philippe.

UPDATE:

More details.

Indeed this works perfectly. No issue here.

I still encounter this problem. But for me this is not insurmountable. At least one of the classes is not abstract, so choosing the order correctly is fine.

More information on this. Upon further inspection, I only encounter this error on methods that are overloaded and whose access changes. So I see this for a method that is protected in AbstractBase and public in myObject. But if I make the method public in both classes, the error does not appear. (Have I done something stupid here?)

Anyway, I have worked around it, so for me this is no longer a problem and I guess this issue has been addressed for future versions of ROOT.

Thanks for your help.

[quote]So I see this for a method that is protected in AbstractBase and public in myObject. But if I make the method public in both classes, the error does not appear. (Have I done something stupid here?)[/quote]This is an odd construct but legal in C++. However the way the support for derived function calling is done in CINT this is indeed a problem (it tries to avoid writing the wrapper for the virtual function in the derived class).

Cheers,
Philippe.