|
Writing ROOT Classes |
|||||||||
ROOT DocumentationThe first place to start is the ROOT User's Guide, Chapter 13 Adding a Class. TObjectAll ROOT classes should derive (inherit from) TObject. For example: class McEvent : public TObject In addition, to use Run Time Type Identification (RTTI) and object I/O - which you will want if you expect to write your ROOT object to a file - then you need to insert the following macros in your ROOT class: First inside the class declaration, in the header file: class McEvent : public TObject { ClassDef(McEvent,1) // The Monte Carlo Event Next inside the class source file, there will be: The Default ConstructorEvent ROOT class must have a default constructor. Be sure, that the default constructor does not allocate any memory - this will cause a memory leak. Machine Independent TypesSince different machines may have different lengths for the same type - ROOT provides a set of predefined types that are guaranteed to be machine independent. For a full list of the available types see the Rtypes.h file in your $ROOTSYS/include directory. When defining your class, be sure to use the machine independent types. Here is a list: Char_t signed character 1 byte NOTE: Long_t and ULong_t are not yet machine independent - do not use them!!! CLHEP ClassesROOT provides many of the same types of classes that CLHEP
does. It is necessary to use the ROOT equivalent of the CLHEP
classes, for example:
CollectionsOften you will want to store a collection of objects. ROOT provides a variety of mechanisms to accomplish this. TObjArray TClonesArray STL It is also possible to use the STL classes: vector, map, etc. There is an example in the Skeleton section below. Pointers to other objectsIn general pointers should not be stored in a ROOT class. However, if you wish to reference a ROOT object that is also stored in another branch - you can do so using TRef. Byte-OrderingFor an introduction, please see Rene Brun's post to roottalk. Basically, we want to be aware of the compiler's desire to order data members on byte boundaries. What is a 8-byte boundary? Or a 4-byte boundary? An 8-byte boundary is an address that is divisible by 8 without any remainder. For example a double which is 8 bytes would reside in bytes 0 to 7. For example, 2-byte data members will be stored on 2-byte boundaries, 4-byte data members will be stored on 4-byte boundaries, etc. To do so, it may be necessary to insert padding to move a data member to appropriate boundary. We would like to avoid padding as much as possible since it wastes space and creates more work when trying to read in the data. We keep this in mind when ordering our data members in our classes. Rene provided an example: class MyClass { Resulting in the following: Instead we can do: Resulting in: LinkDef FilesIf you are adding a class to an existing ROOT class package, you will notice a file named *LinkDef.h. This file is used when generating ROOT streamer methods. These methods are used to actually perform the ROOT I/O. You do not need to worry about this - except the following: For each ROOT class, there must be a line declaring the class in the *LinkDef.h file. For example: #pragma link C++ class McEvent+; A SkeletonHere is an example ROOT class: |
Legacy Documentation owned by: H. Kelly (Last Modified: 2002-04-25 09:07:00 -0700 )
Last updated by: Chuck Patterson 01/20/2006 |