// @(#)root/meta:$Name: p16-br-05 $:$Id: TClassRef.cpp,v 1.1 2003/01/09 18:09:58 axel Exp $
// Author: Axel Naumann <mailto:axel@fnal.gov> 01/08/2002
/*************************************************************************
* Copyright (C) 1995-2002, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#include "tmb_tree/TClassRef.hpp"
#include "TROOT.h"
#include "TClass.h"
/////////////////////////////////////////////////////////////
// Persistent reference to a TClass.
// (TClass itself is not persistent.)
//
// Implements Compare(), IsEqual() and Hash() (mostly
// by forwarding to TClass), and can thus be used e.g.
// as a key for TMap.
//
// Example application:
// A TMap which stores objects of different types, not
// necessarily known during compile time. The objects'
// TClass can be used to access the objects in the map.
// Thus at compile time the container does not need to
// know the type of the objects stored.
//
// Let's assume one wants to store these classes:
//
// class TSomeObject: public TCommonBase {...};
// class TOtherObject: public TCommonBase {...};
//
// Instead of
//
// class THasObjects {
// public:
// TSomeObject* GetSomeObject() { return fObjects[0]; }
// TOtherObject* GetOtherObject() { return fObjects[1]; }
// private:
// TCommonBase* fObjects; // array of objects
// };
//
// (which can't be extended in a modular way or at
// runtime to allow for additional objects) one could
// use:
//
// class TClassMap {
// public:
// TClassMap(){ fMap.SetOwner(); }
// TObject* GetValue(TClass* cl) {
// TClassRef cr(cl);
// return fMap.GetValue(&cr);
// }
// void Add(TObject* obj) {
// fMap.Add(new TClassRef(obj->IsA()), obj);
// }
// private:
// TMap fMap;
// };
//
// Here, TClassMap does not know anything about the objects
// it contains. TCommonBase class could access them like
// this:
//
// class TCommonBase: TObject {
// TCommonBase* LookMeUp(TClassMap* cm) {
// return (TCommonBase*) cm->GetValue(IsA());
// }
// };
//
// Objects of class TClassMap can be stored as its TMap
// contains keys of class TClassRef instead of class TClass.
//
////////////////////////////////////////////////////////////
ClassImp(TClassRef)
// Tag used as "class name" to indicate a TClassRef's
// fClass was uninitialized when written.
// Use invalid C(++) characters to ensure no class
// can ever have this name and that this class name's
// TClass can never be found.
#define UNDEFINED_CLASS_TAG ("@ @")
Int_t TClassRef::Compare(const TObject * obj) const
{
// Compare two TClassRefs or a TClassRef with a TClass
// Forwards the implementation to the referenced TClass::Compare()
if (!fClass) {
Warning("Compare", "Class not set, nothing to compare.");
return 0;
}
if (obj->InheritsFrom(TClass::Class()))
return fClass->Compare(obj);
else if (obj->InheritsFrom(TClassRef::Class()))
return fClass->Compare(((TClassRef *) obj)->GetClass());
Warning("Compare", "Can't compare TClassRef to %s!",
obj->IsA()->GetName());
return 0;
}
ULong_t TClassRef::Hash() const
{
// Creates a hash value.
// Forwarded to TClass->Hash() if a referenced class is set,
// otherwise fallback to TObject::Hash()
return (fClass ? fClass->Hash() : TObject::Hash());
}
void TClassRef::SetClass(const char *clname)
{
// Sets clname to be the referenced class.
// A warning is issued if the class is unknown, and the class
// returned by GetClass() is set to NULL.
fClass = gROOT->GetClass(clname, kTRUE);
if (!fClass)
if (strcmp(clname, UNDEFINED_CLASS_TAG) == 0)
Warning("TClassRef",
"Referenced class was undefined when writing!");
else
Warning("TClassRef", "Class '%s' unknown!", clname);
}
void TClassRef::Streamer(TBuffer & R__b)
{
// Stream an object of class TClassRef.
// Format:
// UInt_t string len of classname
// 0 terminated char* classname
// first stream the base class
TObject::Streamer(R__b);
if (R__b.IsReading()) {
// allocate a heap char[] if the classname
// is too big to fit into the static char[].
#define staticstrlen 4096
static char clnamestatic[staticstrlen];
char *clname = clnamestatic;
UInt_t len;
R__b >> len;
if (len > staticstrlen)
clname = new char[len + 1]; // static char[] is not big enough
R__b.ReadString(clname, -1); // disable size check, we know the length
SetClass(clname); // initialize *this
if (len > staticstrlen)
delete[]clname;
} else {
if (!fClass)
Warning("Streamer", "Writing TClassRef to undefined class!");
const char *clname;
if (fClass)
clname = fClass->GetName();
else
clname = UNDEFINED_CLASS_TAG;
R__b << (UInt_t) strlen(clname);
R__b.WriteString(clname);
}
}
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.