Re: [ROOT] Streamer of a class containing a TClonesArray

From: Rene Brun (Rene.Brun@cern.ch)
Date: Thu Jun 07 2001 - 09:00:42 MEST


Hi David,

With the old Streamers prior to version 3, we had a special case for
TClonesArray. It was assumed that the TClonesArray exists when Streamer
is called because it does not make too much sense to recreate the TClonesArray
for each entry.

With version 3, the new automatic Streamers do not make this assumption
anymore. We have implemented the convention with the "->" in the comment field
to indicate that the system can assume that the TClonesArray object exists
when Streamer is called.

Note that to get the automatic Streamers, you must specify append 
the character "+" at the end of the class name in the pragma statement of your
LinkDef.h file.

We are currently polishing teh documentation to describe all these points
in more details. The new doc should be available shortly.

Rene Brun


GUEZ David wrote:
> 
> Hello,
> 
> In the exemple program bellow, I have reproduced a strange problem...
> 
> -----------------------------------------------------------------------
> 
> With the code
> 
> #include <iostream>
> 
> #include <TROOT.h>
> #include <TClonesArray.h>
> 
> class A :public TObject
> {
>  protected:
>   Int_t fX;
> 
>   TClonesArray *pb; // here is the problem source...
> >>>>---------------------------------------<<<<<
> 
>  public:
>   A():TObject(){cout<<"Default A constructor"<<endl; fX=0;}
>   A(Int_t x):TObject(){cout<<"Creating A with x="<<x<<endl;fX=x;}
>   ~A(){cout<<"Deleting A with x="<<fX<<endl;}
>   Int_t X() const {return fX;}
>   Int_t X(Int_t x){return fX=x;}
>   ClassDef(A,1)
> };
> 
> the copy of the dict.cxx file generated by rootcint is
> 
> void A::Streamer(TBuffer &R__b)
> {
>    // Stream an object of class A.
> 
>    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 >> fX;
> 
>       pb->Streamer(R__b);
> >>>>----   My Problem .... ----------<<<<<<<<<
> 
>       R__b.CheckByteCount(R__s, R__c, A::IsA());
>    } else {
>       R__c = R__b.WriteVersion(A::IsA(), kTRUE);
>       TObject::Streamer(R__b);
>       R__b << fX;
>       pb->Streamer(R__b);
>       R__b.SetByteCount(R__c, kTRUE);
>    }
> }
> ------------------------------------------------------------------------
> 
> As you can see, this streamer expect <pb> to be well instanciated.
> Since
> 1) the default constructor is supposed to not allocate memory,
> and 2) this default constructor is used on file reading
> then, as you can imagine, I'm facing a
>  *** Break *** segmentation violation
> error.
> I also add a -> on comments but nothing is changed (and I think that
> this
> should be used exactly for the opposite goal....)
> This is really strange, because, if I replace TClonesArray* by TTree*
> (for instance) the code generated use a "normal" R__b>>pb
> Then, since it's a special case, may be I miss a special rule, but, if
> so, please tell me which one
> 
>         Thanks in advance
>                 DAVID
> 
> --
> David GUEZ
> davguez@mail.dotcom.fr
> WEB : www.fairesuivre.com/~davguez
> ICQ : 6229724



This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:48 MET