Re: Persistency & Polymorphism

From: Axel Naumann <Axel.Naumann_at_cern.ch>
Date: Mon, 12 Feb 2007 16:19:52 +0100


Hi Christian,

i/o is done in a recursive way, where ROOT iterates through the base classes. Your base class AbsTrackRep will need a dictionary. TObject has one as well, even though almost nobody ever stores a pure TObject to file: it's needed for all the classes derived from TObject, too. And it does not matter that AbsTrackRep is abstract.

So just add
#pragma link C++ class AbsTrackRep+;

Cheers, Axel.

Christian Hoeppner wrote:
> Hello,
>
> I have thew following problem I want to solve with ROOT:
>
> I want to make an instance of class called "Track" persistent to a ROOT
> file.
>
> "Track" contains a collection of TrackReps (which are track
> representations used with a Kalman filter). There is an abstract base
> class "AbsTrackRep" (which inherits from TObject), and derived from that
> are e.g. "HelixTrackRep" and "StraightLineTrackRep" (or in general
> "ConcreteTrackRep").
>
> I figure that the right collection is a "TObjArray", since it contain a
> collection of whatever, as long as everything inherits from TObject.
> Please note, that the Array will never contain any instances of
> "AbsTrackRep" but only different "ConcreteTrackReps".
>
> However, when trying to persist, I get an error message:
>
> No dictionary for AbsTrackRep
>
> This is completely true, because this abstract base class doesn't have
> one, it can't even be instanciated. The "ConcreteTrackRep"s however have
> dictionaries, and these are the ones which should be used.
>
>
> Here is what I could track down what happens when the TObjArray Streamer
> is called:
>
> TObjArray has a method Streamer which is used for writing to the IO. It
> uses the << operator of TBuffer to do so. This operator uses the
>
> Int_t TBuffer::WriteObjectAny(const void *obj, const TClass *ptrClass)
>
> method. In this method something strange seems to happen:
>
> temp -= clActual->GetBaseClassOffset(ptrClass);
> WriteObject(temp, clActual);
>
> This code somehow gets the adress of the base class and tries to call the
> dictionary for the base class. And this is exactly where the "no dictionary"
> error comes from. I tried this one the CINT command line after I loaded my
> shared lib. The clActual points to a HelixTrackRep and temp to AbsTrackRep.
>
> Finally my question: Does anyone know how to work around this. E.g. is there
> some pragma for the linkdef to tell root not to look for the base class
> in the WriteObjectAny method?
>
>
> Cheers, Christian
>
>
>
Received on Mon Feb 12 2007 - 16:19:59 CET

This archive was generated by hypermail 2.2.0 : Mon Feb 12 2007 - 23:50:01 CET