Hi René, I use the version 3.05/00 on a linux platform | root [11] c3->GetParent() | (class TestClass*)0x899c098 | root [12] c | (class TestClass*)0x899c098 That's not what i want . I would like c3->GetParent() to return the address of c2. With the automatically generated streamer it returns 0, i would have thought it would return the address of c. So I've customized the streamer : void TestClass::Streamer(TBuffer &R__b) { // Stream an object of class TestClass. UInt_t R__s, R__c; if (R__b.IsReading()) { Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { } TObject::Streamer(R__b); R__b >> fList; ////// that's what i've added ////////// TIter next(fList); TestClass2*c2; while( (c2=(TestClass2*)next()) ){ c2->SetParent(this); } ///////////////////////////////////////////// R__b.CheckByteCount(R__s, R__c, TestClass::IsA()); } else { R__c = R__b.WriteVersion(TestClass::IsA(), kTRUE); TObject::Streamer(R__b); R__b << fList; R__b.SetByteCount(R__c, kTRUE); } } i thought - naively - that it would then set the TRef to the address of the object being build through the streamer. So what must i do to correctly set the TRefs of the objects in the list so that they actually point to their real parent ? can it be done through the streamer ? Le Jeudi 17 Avril 2003 17:56, vous avez écrit : | Hi Alexis, | | Unfortunately, you do not indicate which version of Root and OS. | I cannot reproduce your problem. Using your .H and .C files, I have | created a shared lib mignon.so, then run the following session: | | root [0] .L mignon.so | root [1] TestClass* c=new TestClass; | root [2] c->Add("first"); | root [3] c->Add("second"); | root [4] c->Add("third"); | root [5] c.ls() | OBJ: TestClass TestClass test class : 0 at: 0x899c098 | root [6] TestClass* c2=(TestClass*)c->Clone(); | root [7] c2.ls() | OBJ: TestClass TestClass test class : 0 at: 0x89a37d0 | root [8] TestClass2* c3=(TestClass2*)c2->GetList()->First(); | root [9] c3 | (class TestClass2*)0x89d2368 | root [10] c3.ls() | OBJ: TestClass2 first testclass2 : 0 at: 0x89d2368 | root [11] c3->GetParent() | (class TestClass*)0x899c098 | root [12] c | (class TestClass*)0x899c098 | | AS you can see, results seem to be correct. | | Rene Brun | | Mignon Alexis wrote: | > Hello, | > | > I have a problem with some circular refernces when i try to make a | > clone of an object. | > | > i have for instance 2 objects : | > | > /////////////////// TestClass.H /////////////////////// | > | > #ifndef __TestClass__ | > #define __TestClass__ | > | > #include <TList.h> | > #include "TestClass2.H" | > class TestClass2; | > class TestClass : public TObject { | > protected : | > TList *fList; // -> list | > | > public : | > TestClass(); | > ~TestClass(); | > | > TestClass2* Add(const Char_t *name); | > TList* GetList() const; | > ClassDef(TestClass,1) //test class | > }; | > | > inline TList*TestClass::GetList() const{ | > return fList; | > } | > | > #endif | > \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ | > and | > /////////////// TestClass2.H /////////////////////////// | > #ifndef __TestClass2__ | > #define __TestClass2__ | > | > #include <TNamed.h> | > #include <TRef.h> | > #include "TestClass.H" | > | > class TestClass; | > class TestClass2 : public TNamed{ | > protected: | > TRef fClassTest; // back reference | > | > public: | > TestClass2(); | > TestClass2(const Char_t* name, TestClass* tc); | > ~TestClass2(); | > | > TestClass* GetParent(); | > void SetParent(TestClass*c); | > | > ClassDef(TestClass2,1) //test class 2 | > | > }; | > | > inline TestClass* TestClass2::GetParent(){ | > return (TestClass*)fClassTest.GetObject(); | > } | > | > #endif | > | > \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ | > | > with the default streamer when i do | > | > TestClass* c=new TestClass; | > c->Add("first"); | > c->Add("second"); | > c->Add("third"); | > | > TestClass* c2=(TestClass*)c->Clone(); | > | > TestClass2* c3=(TestClass2*)c2->GetList()->First(); | > | > then | > c3->GetParent() returns the null pointer (why not the pointer to c | > ?) | > | > to set the parent member of TestClass2 | > | > i've modified the streamer of TestClass so that it does a | > class2->SetParent(this) for each object in its list. | > | > but then | > | > c3->GetParent() returns the pointer to c instead of c2 . | > | > What must i do in order to get the good parent pointer to the clone | > of the first object | > | > this is the source code for the 2 classes : | > | > ////////////////////////// TestClass.C //////////////////////////// | > | > #include "TestClass.H" | > #include <TCollection.h> | > | > ClassImp(TestClass); | > | > TestClass::TestClass(){ | > fList=0; | > } | > | > TestClass::~TestClass(){ | > if(fList) { | > fList->Delete(); | > delete fList; | > } | > } | > | > TestClass2* TestClass::Add(const Char_t*name){ | > if (!fList) fList=new TList; | > TestClass2*c=new TestClass2(name, this); | > fList->Add(c); | > return c; | > } | > void TestClass::Streamer(TBuffer &R__b) | > { | > // Stream an object of class TestClass. | > | > UInt_t R__s, R__c; | > if (R__b.IsReading()) { | > Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { | > } TObject::Streamer(R__b); | > R__b >> fList; | > TIter next(fList); | > TestClass2*c2; | > while( (c2=(TestClass2*)next()) ){ | > c2->SetParent(this); | > } | > R__b.CheckByteCount(R__s, R__c, TestClass::IsA()); | > } else { | > R__c = R__b.WriteVersion(TestClass::IsA(), kTRUE); | > TObject::Streamer(R__b); | > R__b << fList; | > R__b.SetByteCount(R__c, kTRUE); | > } | > } | > | > \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ | >\\\\\ | > | > and | > | > ////////////////////////// TestClass2.C | > //////////////////////////// #include "TestClass2.H" | > | > ClassImp(TestClass2); | > | > TestClass2::TestClass2(){ | > fClassTest=0; | > } | > | > TestClass2::TestClass2(const Char_t *name, TestClass* tc) | > | > : TNamed(name,"testclass2"){ | > | > fClassTest=tc; | > } | > | > TestClass2::~TestClass2(){ | > } | > | > void TestClass2::SetParent(TestClass *c){ | > fClassTest=c; | > } | > \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ | >\\\\ -- | > Alexis Mignon | > GANIL | > Bd Henri Becqurel | > 14076 CAEN Cedex 5 | > France | > tel: +(33) (0)231454680 | > e-mail : mignon@ganil.fr -- Alexis Mignon GANIL Bd Henri Becqurel 14076 CAEN Cedex 5 France tel: +(33) (0)231454680 e-mail : mignon@ganil.fr
This archive was generated by hypermail 2b29 : Thu Jan 01 2004 - 17:50:11 MET