Pasha Murat wrote: > > I have a couple of questions about ROOT arrays - after > looking over the documentation for quite a while I felt like > I still don't have all the answers. > > - how does the TObjArray know the number of elements in it? It is smart: > it doesn't do compression when one of its objects is deleted therefore > it allows "holes" in its structure. > Does it mean that to get the number of objects in TObjArray one has to > calculate this number explicitly by iterating over the collection each time > he needs it? > The are two cases: - no holes: TObjArray::GetEntriesFast() returns number of objects in array. Note: this is <= size of array (returned by TObjArray::Capacity() or GetSize()). - holes: TObjArray::GetEntries() returns number of objects in array (done by looping over array, thus expensive). In both cases GetLast() returns the index of the last occupied slot in the array (slot <= size). To loop over the complete array do: for (int i = arr.LowerBound(); i < arr.GetLast(); i++) if (arr[i]) { ... } By default LowerBound() is 0, so one can do: for (int i = 0; i < arr.GetLast(); i++) if (arr[i]) { ... } Or use the standard TIter technique: TIter next(arr); TObject *obj; while (obj = next()) { ... } The iterator steps over empty slots so not check for 0 object is needed. > > - Is it possible to put an existing object into ROOT collection without > creating its clone on heap? > What happens if a locally defined object has been added to a collection? > Is it always necessary to use new? > If the answer to the previous quiestion is "yes", it means that collection > doesnt' own its objects in a sense that they've been created outside the > collection. So what happens then with the objects when collection gets > deleted? Who keeps the responsibility for deleting the objects? > ROOT collections store pointers to TObjects. The pointer may point to a heap based object or to a stack based (local) object. In the later case one must take care to remove the object from the collection just before the object goes out of scope (this can be done by the object dtor in case the object knows in which collection it is stored). A collection can be an "owning" collection. I.e. it will take care of deleting the objects which pointers are stored in it. This is done via TCollection::Delete(). In Delete() the collection is iterated and every object is deleted (except for stack based objects, since they will be deleted by the C++ run-time). The whole thing of "ownership" is a matter of convention and not explicitely enforced. For example: class Event : public TObject { private: TList *fTracks; TList *fVertex1; TList *fVertex2; ... public: virtual ~Event() { if (fTracks) fTracks->Delete(); delete fTracks; delete fVertex1; delete fVertex2; } }; Assume that in the above class fTracks is an "owning" collection. It owns the tracks stored in it (no other references to the tracks are available). And fVertex1 and fVertex2 are lists containing a, possible overlapping, subset of tracks that belong to either of the two vertex candidates. The two vertex track lists don't own the objects stored in it. So in the Event dtor we have to call fTracks->Delete() to delete all tracks. The TList dtors just reclaim the TList data structure. Cheers, Fons. -- 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
This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:26:21 MET