Valeri,
To do I/O, you have to modify the Bclass::Streamer function.
See my changes in the files below:
Rene Brun
//--------------file 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
//---------------test.h
#include "TObject.h"
class Aclass
{
protected:
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); }
void SetApr(int apr) {a_member_private=apr;}
// 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();
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)
};
//-------------file test.cxx
#include "test.h"
ClassImp(Bclass)
Bclass::Bclass() :Aclass()
{
b_member = 1234;
}
Bclass::Bclass( int apr, int apu, int bpr ) : Aclass( apr, apu )
{
b_member = bpr;
}
//______________________________________________________________________________
void Bclass::Streamer(TBuffer &R__b)
{
// Stream an object of class Bclass.
if (R__b.IsReading()) {
Version_t R__v = R__b.ReadVersion(); if (R__v) { }
TObject::Streamer(R__b);
R__b >> b_member;
int apr;
R__b >> apr; SetApr(apr);
R__b >> a_member_public;
} else {
R__b.WriteVersion(Bclass::IsA());
TObject::Streamer(R__b);
R__b << b_member;
R__b << GetApr();
R__b << GetApu();
}
}
On Mon, 14 Feb 2000, Valeri Tioukov wrote:
> 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