always use ClassDef/ClassImp even in non-TObject classes.
You are quite right to question the TObject overhead. In case you
have many millions of small 2 byte objects in memory the overhead
is relatively large. However, if you only have a few thousand of such
objects in memory it becomes quite reasonable to use TObject as
base class. I suspect you will have only a few thousand in memory,
but will collect many millions in Trees. In that case it is still
quite reasonable since, as you suspect, the fBits and fUniqueID
are basically constants and will be compressed away by the Tree
buffer compression algorithm (fBits contains some flags, like if
the object is on the heap, etc. fUniqueID is 0 for the time being).
Cheers, Fons.
Rutger van der Eijk wrote:
>
> Hi Fons,
>
> Thanks for your reply. At the moment I'm not using pointers to
> non-TObjects so thats oke for now.
>
> There is still a thing which is not completly clear for me. What should I
> include in my none-TObject class declaration to make rootcint able to
> generate the Streamer member function? Including only the Streamer
> declaration gives error messages like:
>
> Error: Can't call MTChannelId::Class_Version() in current scope FILE:
> LINE:0
> Error: No symbol MTChannelId::Class_Version() in current scope FILE:
> LINE:0
> Class MTChannelId: ShowMembers() not declared
>
> or should I just include ALL the member functions as are 'defined' by
> using the ClassDef 'statement'? (or which ones AT LEAST?)
>
> (Actually my reason to make a few none-TObject classes is because of my
> fear (or ignorance) of introducing to much 'overhead datamembers bytes'
> in some low-level classes. I by now found out (i.e. have read) that every
> TObject contains 8 bytes of datamembers. On a class which only has 2
> bytes of 'real' datamemebers (and from which I will create millions of
> instances) this seems as a waste of memory/disk space. What is exactly
> written in this fBits and fUniqueID data member of TObjects? Is it
> (almost) the same for all instances, so that I can expect a huge
> compression factor? Or am I wise by not inheriting from TObject for these
> essential, low size classes?)
>
> Thanks, and keep up the good work,
>
> Rutger van der Eijk
>
> On Mon, 23 Mar 1998, Fons Rademakers wrote:
>
> > Hi Rutger,
> >
> > for non-TObject classes you need to provide a custom TBuffer &operator>>()
> > and TBuffer &operator<<() in case you want to be able to save the objects
> > via pointers to such objects. In case you want to save directly the objects
> > (as opposed to pointers to objects) you need only a Streamer().
> > The default generated Streamer() should be ok (depending if you use pointers
> > to basic types, in which case you need to make a custom Streamer()).
> > For example:
> >
> > class MPipo : public TObject { <-- base class goes via TObject::Streamer()
> > private:
> > MAap fAap; <-- goes via MAap::Streamer()
> > MNoot *fNoot; <-- goes via TBuffer &operator<<(), fNoot can be 0
> > ...
> > };
> >
> > A good example of a class having its own operator<< and operator>> is
> > http://root.cern.ch/root/html/src/TArray.cxx.html and see also
> > http://root.cern.ch/root/html/src/TArrayC.cxx.html for special operator>>.
> >
> > In case you don't want rootcint to generate the Streamer() and operator>>
> > you have to put in the LinkDef.h file:
> >
> > #pragma link C++ class TArrayC-!;
> >
> > where - means no Streamer() and ! no operator>>() (can also be only !
> > or -).
> >
> > Currently objects containing non-TObject derived objects can not
> > be stored in Trees in split mode. For this and other rules see:
> > http://root.cern.ch/root/HowtoWriteTree.html
> >
> > Cheers, Fons.
> >
> >
> > Rutger van der Eijk wrote:
> > >
> > > Hi All,
> > >
> > > I'm having problems including some none-TObjects into a (root)shared
> > > library.
> > >
> > > I have a simple Event class (MTRawEvent) declared as follows:
> > > (some members not shown for clarity):
> > >
> > > ---- MTRawEvent.H ----
> > > #ifndef _MTRawEvent_H_
> > > #define _MTRawEvent_H_
> > >
> > > #include "TObject.h"
> > > #include "MTRawHit.H"
> > >
> > > class MTRawEvent: public TObject {
> > > public:
> > > MTRawEvent(); // create uninitialized
> > >
> > > void SetRawHit(MTRawHit rawHit); // temp set hit as long as not array...
> > > MTRawHit GetRawHit() const; // temp get the single raw hit
> > >
> > > virtual ~MTRawEvent(); // destroy Event-object
> > >
> > > ClassDef(MTRawEvent, 1) // RawEvent class
> > > private:
> > > MTRawHit fRawHit; // raw hit
> > > };
> > >
> > > #endif // _MTRawEvent_H_
> > > ---- ----
> > >
> > > It contains a MTRawHit object as datamember, which is NOT a TObject:
> > >
> > > ---- MTRawHit.H ----
> > > #ifndef _MTRawHit_H_
> > > #define _MTRawHit_H_
> > >
> > > #include "MTChannelId.H"
> > >
> > > class MTRawHit {
> > > public:
> > > MTRawHit(MTChannelId channelId = 0, Int_t tdcValue = 0);
> > >
> > > MTChannelId GetChannelId() const; // get channel id
> > > Int_t GetTDCValue() const; // get TDC value
> > >
> > > ~MTRawHit(); // destroy Hit-object
> > >
> > > private:
> > > MTChannelId fChannelId; // channel Id
> > > Int_t fTDCValue; // TDC value
> > > };
> > >
> > > #endif // _MTRawHit_H_
> > > ---- ----
> > >
> > > It contains as datamembers a Int_t and another none-TObject class
> > > MTChannelId.
> > >
> > > My problem:
> > >
> > > The MTRawEvent I (ofcourse) want to somewhere put in a TTree and a TFile.
> > > With rootcint I can then create the appropriate Streamer methods for
> > > classes inheriting from TObject. From reading the ROOT tutorial and
> > > 'course' and browsing the web-pages it doesn't become completely clear
> > > to me what the best procedure is to handle none-TObject classes.
> > >
> > > My questions:
> > >
> > > - Should I (manually) write Streamer (and ShowMember) member functions for
> > > the none-TObjects (MTRawHit and MTChannelId) or should I only modify the
> > > TObject MTRawEvent?
> > > - If I write (or modify) a Streamer member function definition should I
> > > also put the declaration in the class declaration? Actually I don't
> > > understand why this seems NOT to be necesarry for TObjects...
> > > - Should I include classes of the none-TObjects in the linkdef.h file
> > > (with #pragma link C++ class MTChannelId-; (or with also '!' ?))
> > >
> > > I would appriciate any help and/or simple-example ,
> > >
> > > Rutger van der Eijk
> >
> > --
> > Org: CERN, European Laboratory for Particle Physics.
> > Mail: 1211 Geneve 23, Switzerland Phone: +41 22 7679248
> > E-Mail: Fons.Rademakers@cern.ch Fax: +41 22 7677910
> >
-- Org: CERN, European Laboratory for Particle Physics. Mail: 1211 Geneve 23, Switzerland Phone: +41 22 7679248 E-Mail: Fons.Rademakers@cern.ch Fax: +41 22 7677910