Re: rootcint and multiple inheritance

From: Valeri Tioukov (valeri@na.infn.it)
Date: Mon Feb 14 2000 - 18:37:58 MET


Dear Rene,

On Sun, 13 Feb 2000, Rene Brun wrote:

> Hi Valeri,
> 
> Yes, this is possible. see your files slightly modified below:
> Run the script creating the shared lib test.so, then run the session:
> Root > gSystem->Load("test");
> Root > Bclass b;
> Root > b.Dump();

the output of last command is:

root [2] b.Dump();             
b_member                 1234        
fUniqueID                0           object unique identifier
fBits                    50331648    bit field status word

so a_member is not visible. 

As I stated in 1-st email I need to store the elements of Aclass (Bclass
is only container) into root file and to make them available for
root-analisys with minimal efforts. 
I think that this problem is fearly actual for users who have
non-Root C++ working applications.

The following example illustrates that this double inheritance scheme does
not work as desired:


//--------test.h------------
#include "TObject.h"

class Aclass
{
 private:
  int   a_member_private;

 public:
  Aclass(){}
  Aclass(int apr, int apu) { a_member_private=apr; a_member_public=apu; }
  virtual ~Aclass(){ }

  int   a_member_public;

  int GetApr()   const {return a_member_private;}
  int GetApu()   const {return a_member_public;}
  int PrintA()   const { printf("PrintA: %d %d \n", a_member_private,a_member_public); }

};

class Bclass
      :public TObject
      ,public Aclass
{
  private:
  int b_member;

 public:
  Bclass(){}
  Bclass( int apr, int apu, int bpr );
  virtual ~Bclass(){}

  void Print() const { PrintA(); printf("PrintB:  a_priv= %d  a_publ= %db= %d\n", GetApr(), GetApu(), b_member); }

  ClassDef(Bclass,1)
};
//---------end of test.h-------------

//-------test.cxx file---------
#include "test.h"
   ClassImp(Bclass)
   
Bclass::Bclass( int apr, int apu, int bpr ) : Aclass( apr, apu )
{
   b_member = bpr;
}
//-------end of test.cxx file---------
//-------b.C - test macro-----------
void w()
{
  gSystem->Load("test");
  Bclass ob(10,20,30);
  ob.Print();
  TFile f("test.root","RECREATE");
  ob.Write("ob");
  f.Write();
  f.Close();
}

void r()
{
  TFile *f = new TFile("test.root");
  Bclass *ob = (Bclass*)f->Get("ob");
  ob->Print();
  TBrowser *br = new TBrowser();
}

void t()
{
  TFile f("test.root","UPDATE");

  TTree *tree = new TTree("T","test tree");
  Bclass  *pb = new Bclass();
  TBranch *branch = tree->Branch("Bclass", "Bclass", &pb, 64000,1);

  for(int i=0; i<100; i++) {
    pb = new Bclass(i,i,i);
    tree->Fill();
  }

  f.Write();
  f.Close();
}
//-------end of b.C - test macro-----------

now if we do:

root [0] .L b.C
root [1] w()                 // print on the screen and write to file
PrintA: 10 20 
PrintB:  a_priv= 10  a_publ= 20  b= 30
root [2] t()                 // write the root tree
root [3] r()                 // read from file and print on the screen
 PrintA: 0 0 
PrintB:  a_priv= 0  a_publ= 0  b= 30

we see that the elements of Aclass did not stored did not dumped and
did not inspected correctly by root.
No wonder, because rootcint do not generate streamer and showmember 
stuff for members of Aclass: in testcint* files there are nothing
appropriate.

Moreover: if I inspect tree by the graphical browser and double click on
fBits it's blocks compleatly the root session (why BTW?). (Root 2.23/12 /RH5.1)


So I repeate the original question: is it possible to make the members of
Aclass available for storage in the root file and for root-analisys
without any changements in Aclass body?


Best regards
Valeri





> 
> Rene Brun
> 
> //----script to create a small shared lib on Linux
> rootcint -f testcint.cxx -c test.h LinkDef.h
> g++ -g -fPIC -I$ROOTSYS/include -c testcint.cxx test.cxx
> g++ -g -Wl,-soname,test.so -shared testcint.o test.o -o test.so 
> 
> 
> //----LinkDef.h file
> #ifdef __CINT__
> 
> #pragma link off all globals;
> #pragma link off all classes;
> #pragma link off all functions;
> 
> #pragma link C++ class Bclass;
> 
> #endif
> 
> 
> //-----test.h
> #include "TObject.h"
> 
> class Aclass
> {
>  private:
>   int   a_member;
> 
>  public:
>   Aclass(){}
>   virtual ~Aclass(){}
> 
>   //  ClassDef(Aclass,1)   // if this line commented - a_member is hidden
> from root
> };
> 
> class Bclass
>       :public TObject
>       ,public Aclass
> {
>   private:
>   int b_member;
> 
>  public:
>   Bclass();
>   virtual ~Bclass(){}
> 
>   ClassDef(Bclass,1)
> };
> 
> //-------test.cxx file
> #include "test.h"
>    ClassImp(Bclass)
>    
> Bclass::Bclass() :Aclass()
> {
>    b_member = 1234;
> }
> 
> 
> On Wed, 9 Feb 2000, Valeri Tioukov wrote:
> 
> > Hi Rooters,
> > 
> > If I have class  Aclass  used by external application and I do not want to
> > do ANY changement in this class, but I'd like to make it's memebers and
> > functions visible to Root system (for storage and analisys purpose)
> > inheriting new Bclass as following:
> > 
> > class Bclass
> >       :public TObject
> >       ,public Aclass
> > 
> > Is it possible?
> > 
> > I investigate that without including macros   ClassDef(Aclass,1) into the
> > body of Aclass  rootcint do not generate  Streamer() and  
> > ShowMembers() functions. Just mentioning of Aclass in LinkDef.h do not
> > helps.
> > 
> > So it seems that the answer is NOT: it is not possible to make the members
> > of classA visible to Root without changements of classA body.
> > 
> > But the same question was asqued at least twice:
> > 
> > http://root.cern.ch/root/roottalk/roottalk98/1986.html
> > http://root.cern.ch/root/roottalk/roottalk98/0107.html
> > 
> > and in both cases the answers were a bit confusing but positive.
> > 
> > Why do not find the definite answer and add it to FAQ? 
> > 
> > I used for tests:
> > ----------------test.h------------
> > #include "TObject.h"
> > 
> > class Aclass
> > {
> >  private:
> >   int   a_member;
> > 
> >  public:
> >   Aclass(){}
> >   virtual ~Aclass(){}
> > 
> >   //  ClassDef(Aclass,1)   // if this line commented - a_member is hidden  from root
> > };
> > 
> > class Bclass
> >       :public TObject
> >       ,public Aclass
> > {
> >   private:
> >   int b_member;
> > 
> >  public:
> >   Bclass():Aclass(){}
> >   virtual ~Bclass(){}
> > 
> >   ClassDef(Bclass,1)
> > };
> > -----------------------------------
> > 
> > ---------LinkDef.h----------------------
> > #ifdef __CINT__
> > 
> > #pragma link off all globals;
> > #pragma link off all classes;
> > #pragma link off all functions;
> > 
> > #pragma link C++ class Aclass;
> > #pragma link C++ class Bclass;
> > 
> > #endif
> > ---------------------------------------
> > 
> > 
> > Without the commented line command
> > 
> >  >  rootcint -f test_h.C -c test.h LinkDef.h
> > 
> > do not care about members of Aclass.
> > 
> > 
> > Best regards
> > Valeri
> > 
> 
> 



This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:18 MET