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