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