Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:11:54

0001 // @(#)root/geom:$Id$
0002 // Author: Andrei Gheata   29/05/2013
0003 
0004 /*************************************************************************
0005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
0006  * All rights reserved.                                                  *
0007  *                                                                       *
0008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0010  *************************************************************************/
0011 
0012 #ifndef ROOT_TGeoRCPtr
0013 #define ROOT_TGeoRCPtr
0014 
0015 /** \class TGeoRCPtr
0016 \ingroup Geometry_classes
0017 
0018 A reference counting-managed pointer for classes derived from TGeoExtension
0019 which can be used as C pointer. Based on CodeProject implementation example
0020 
0021 ### Example:
0022 
0023 ~~~ {.cpp}
0024 class MyExtension : public TGeoExtension {
0025 public:
0026    MyExtension() : TGeoExtension(), fRC(0) {printf("Created MyExtension\n");}
0027    virtual ~MyExtension() {printf("Deleted MyExtension\n");}
0028 
0029    virtual TGeoExtension *Grab() const {fRC++; return (TGeoExtension*)this;}
0030    virtual void Release() const {assert(fRC > 0); fRC--; if (fRC ==0) delete this;}
0031    void print() const {printf("MyExtension object %p\n", this);}
0032 private:
0033    mutable Int_t        fRC;           // Reference counter
0034    ClassDefOverride(MyExtension,1)
0035 };
0036 ~~~
0037 
0038 ### Usage:
0039 
0040 ~~~ {.cpp}
0041  // Module 1 creates an object
0042  TGeoRCPtr<MyExtension> a2 = new MyExtension(); //fRC=1
0043 
0044  // Module 2 grabs object
0045  TGeoRCPtr<MyExtension> ptr2 = a2; //fRC=2
0046 
0047  // Module 2 invokes a method
0048  ptr2->Print();
0049  (*ptr2).Print();
0050 
0051  // Module 1 no longer needs object
0052   a2 = 0;      //RC=1
0053 
0054  // Module 2 no longer needs object
0055   ptr2 = 0;    //object will be destroyed here
0056 ~~~
0057 
0058 ### Note:
0059 
0060 Event if one forgets to call ptr2 = 0, the object gets delete when the method
0061 using ptr2 gets out of scope.
0062 */
0063 
0064 template <class T>
0065 class TGeoRCPtr {
0066 public:
0067    // Construct using a C pointer, e.g. TGeoRCPtr<T> x = new T();
0068    TGeoRCPtr(T *ptr = nullptr) : fPtr(ptr)
0069    {
0070       if (ptr)
0071          ptr->Grab();
0072    }
0073 
0074    // Copy constructor
0075    TGeoRCPtr(const TGeoRCPtr &ptr) : fPtr(ptr.fPtr)
0076    {
0077       if (fPtr)
0078          fPtr->Grab();
0079    }
0080 
0081    ~TGeoRCPtr()
0082    {
0083       if (fPtr)
0084          fPtr->Release();
0085    }
0086 
0087    // Assign a pointer, e.g. x = new T();
0088    TGeoRCPtr &operator=(T *ptr)
0089    {
0090       if (ptr)
0091          ptr->Grab();
0092       if (fPtr)
0093          fPtr->Release();
0094       fPtr = ptr;
0095       return (*this);
0096    }
0097 
0098    // Assign another TGeoRCPtr
0099    TGeoRCPtr &operator=(const TGeoRCPtr &ptr) { return (*this) = ptr.fPtr; }
0100 
0101    // Retrieve actual pointer
0102    T *Get() const { return fPtr; }
0103 
0104    // Some overloaded operators to facilitate dealing with an TGeoRCPtr as a conventional C pointer.
0105    // Without these operators, one can still use the less transparent Get() method to access the pointer.
0106    T *operator->() const { return fPtr; }            // x->member
0107    T &operator*() const { return *fPtr; }            //*x, (*x).member
0108    operator T *() const { return fPtr; }             // T* y = x;
0109    operator bool() const { return fPtr != nullptr; } // if(x) {/*x is not NULL*/}
0110    bool operator==(const TGeoRCPtr &ptr) { return fPtr == ptr.fPtr; }
0111    bool operator==(const T *ptr) { return fPtr == ptr; }
0112 
0113 private:
0114    T *fPtr; // Actual pointer
0115 };
0116 
0117 #endif