Deriving from TCollection

Hi,

Is there some documentation somewhere on how to properly write a custom TCollection (that is, a user class that would adhere to TCollection’s interface) ?

Thanks,

No there is no special documentation. However it if fairly simple, just look at other collections as example.

Cheers, Fons.

Maybe I should be more explicit on the problem I’m facing. I’m concerned about how to stream my custom collection.
From what I see in the code, by inheriting from TCollection, I also inherit the TCollection::Streamer, which relies on 3 things : GetSize() being correctly implemented to return the actual number of objects in the collection, an iterator for TIter to work with, and Add(TObject*) to append objects to the collection.
This is all right, except if I have a data member in my collection, like a boolean flag for instance (e.g. fOptimizeForSomething). I guess this data member won’t be streamed unless I write a custom streamer, is that correct ? If it is, I’m confused as when/whether my custom streamer will be called ?
and how I should code it ?

Regards,

Just use the automatic streamer option (+ in linkdef file) to stream all collection data members.

Cheers, Fons.

I must be dumb… but there’s still something I do not understand.

Imagine a collection which is a “wrapper” for another one :

class MyCollection : public TCollection
{
public:

virtual void Add(TObject*);
virtual void Clear(Option_t* opt="");
virtual void Delete(Option_t* opt="");
virtual TObject** GetObjectRef(const TObject*) const;
virtual TIterator *MakeIterator(Bool_t dir = kIterForward) const;
virtual TObject *Remove(TObject *obj);

virtual Int_t GetSize() const;

Int_t OptimizeLevel() const { return fOptimizeLevel; }

private:
Int_t fOptimizeLevel;
TList* fList;
};

It seems (but I’m a bit confused, so might be wrong) that if GetSize() is not zero, then when reading back my collection, what happens is that there’s a loop of 0…GetSize()-1 for Add(TObject*) (from TCollection::Streamer ?), and then the fList is streamed as well. So if my Add is just a forward to fList’s Add, I might have a problem…

So, is it true that TCollection::Streamer is called at all in this case ? Or how inheritance is handled ? I tried to read the code, but I must confess that I started from :

void MyCollection::Streamer(TBuffer &R__b)
{
// Stream an object of class MyCollection.

if (R__b.IsReading()) {
R__b.ReadClassBuffer(MyCollection::Class(),this);
} else {
R__b.WriteClassBuffer(MyCollection::Class(),this);
}
}

and got discouraged when hitting the TBufferFile::ReadClassBuffer…

Regards,

The MyCollection::Streamer() is indeed called and it will stream the fOptimizeLevel and the TList calling the proper TList streamer which will stream all objects in the TList. So this should work fine. Does it?

Look at THashList.h/.cxx to see an example of what you want.

Cheers, Fons.

No it does not work.

Is the 0 in ClassDef(THashList,0) important is that respect ?

I’ll try to package a small example showing the problem later today.

Regards,

Here’s a small sample which does not work. My error must be trival, but I do not see it :frowning:

What I do is :

MyCollection c(5)
c.Add(new TObjString(“3”)
c.Print()
TFile f(“toto.root”,“recreate”)
c.Write(“c”,1)
.q
TFile f(“toto.root”)
c
c.Print()

this last statement leads to a bus error
MyCollection.cxx (1.29 KB)
MyCollection.h (804 Bytes)