Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Sep 3, 2010, 12:19:53 AM (14 years ago)
Author:
landauf
Message:

added documentation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/doc/src/libraries/util/SharedPtr.h

    r7284 r7327  
    2727 */
    2828
     29/**
     30    @defgroup SharedPtr SharedPtr<T>
     31    @ingroup Util Object
     32*/
     33
     34/**
     35    @file
     36    @ingroup Util SharedPtr
     37    @brief Definition of the SharedPtr template that is used to manage pointers.
     38
     39    @anchor SharedPtrExample
     40
     41    The orxonox::SharedPtr template can be used to manage a pointer to an object
     42    that was created with new. The SharedPtr acts like the pointer itself, but it
     43    keeps track of the number of references to it. If all references are removed,
     44    SharedPtr deletes the managed object automatically.
     45
     46    Example:
     47
     48    Classic implementation using new and delete:
     49    @code
     50    void someFunction()
     51    {
     52        MyClass* object = new MyClass();            // Create a new instance of MyClass
     53
     54        object->myFunction();                       // Calls MyClass::myFunction()
     55
     56        delete object;                              // Delete the object at the end of the scope
     57    }
     58    @endcode
     59
     60    The same function using SharedPtr:
     61    @code
     62    void someFunction()
     63    {
     64        SharedPtr<MyClass> object = new MyClass();  // Create a new instance of MyClass and store its pointer in a SharedPtr
     65
     66        object->myFunction();                       // Calls MyClass::myFunction()
     67
     68    }                                               // At the end of the scope, the SharedPtr is destroyed. Because no other SharedPtrs
     69                                                    // point at the object, the object itself is also destroyed automatically
     70    @endcode
     71
     72    This is especially handy if you do not know what will happen with an object that was
     73    created with new, for example if you pass it to another object. If multiple instances
     74    share a pointer to the same object, none of these instances can delete the object
     75    without interfering with the other instances. But if none of the instances destroy the
     76    object, it will never be destroyed and results in a memory leak. With a SharedPtr
     77    however you don't have to think about destroying the object, because the SharedPtr
     78    itself keeps track of the references.
     79
     80    Example:
     81
     82    Classic implementation using new and delete:
     83    @code
     84    class OtherClass                                    // Declaration of some class
     85    {
     86        public:
     87            OtherClass(MyClass* object)                 // Constructor
     88            {
     89                this->object_ = object;                 // Assigns the pointer to the member variable object_
     90            }
     91
     92            ~OtherClass()                               // Destructor
     93            {
     94                ???                                     // What to do with object_?
     95            }
     96
     97        private:
     98            MyClass* object_;                           // A pointer to the object
     99    };
     100
     101    void someFunction()
     102    {
     103        MyClass* object = new MyClass();                // Create a new instance of MyClass
     104
     105        OtherClass* other1 = new OtherClass(object);    // Create an instance of OtherClass and pass the object pointer
     106        OtherClass* other2 = new OtherClass(object);    // "
     107        OtherClass* other3 = new OtherClass(object);    // "
     108
     109        ???                                             // What happens with object now?
     110    }
     111    @endcode
     112
     113    If you use SharedPtr<MyClass> instead of a classic MyClass* pointer, the instance of
     114    MyClass would be automatically destroyed if all instances of OtherClass are destroyed.
     115    You don't need any code in the destructor and you can completely forget about the
     116    object, because its managed by the SharedPtr.
     117
     118    The same code using SharedPtr:
     119    @code
     120    class OtherClass                                        // Declaration of some class
     121    {
     122        public:
     123            OtherClass(const SharedPtr<MyClass>& object)    // Constructor
     124            {
     125                this->object_ = object;                     // Assigns the pointer to the member variable object_
     126            }
     127
     128        private:
     129            SharedPtr<MyClass> object_;                     // A SharedPtr to the object
     130    };
     131
     132    void someFunction()
     133    {
     134        SharedPtr<MyClass> object = new MyClass();          // Create a new instance of MyClass
     135
     136        OtherClass* other1 = new OtherClass(object);        // Create an instance of OtherClass and pass the object pointer
     137        OtherClass* other2 = new OtherClass(object);        // "
     138        OtherClass* other3 = new OtherClass(object);        // "
     139
     140    }                                                       // The SmartPtr "object" is destroyed at the end of the scope,
     141                                                            // but the three instances of OtherClass keep the object alive
     142                                                            // until they are all destroyed.
     143    @endcode
     144*/
     145
    29146#ifndef _SharedPtr_H__
    30147#define _SharedPtr_H__
     
    39156namespace orxonox
    40157{
    41     class SharedCounter
    42     {
    43         public:
    44             SharedCounter() : count_(1) {}
    45             virtual void destroy() = 0;
    46 
    47             int count_;
    48     };
    49 
    50     template <class T>
    51     class SharedCounterImpl : public SharedCounter
    52     {
    53         public:
    54             SharedCounterImpl(T* pointer) : pointer_(pointer) {}
    55 
    56             void destroy()
    57             {
    58                 delete this->pointer_;
    59             }
    60 
    61         private:
    62             T* pointer_;
    63     };
    64 
    65     _UtilExport SmallObjectAllocator& createSharedCounterPool();
    66 
    67     FORCEINLINE SmallObjectAllocator& getSharedCounterPool()
    68     {
    69         static SmallObjectAllocator& instance = createSharedCounterPool();
    70         return instance;
     158    namespace detail
     159    {
     160        /// BaseClass of SharedCounterImpl, has a counter that is initialized with 1
     161        class SharedCounter
     162        {
     163            public:
     164                SharedCounter() : count_(1) {}
     165                virtual void destroy() = 0;
     166
     167                int count_;
     168        };
     169
     170        /// Child class of SharedCounter, keeps a pointer to an object of type T that can be destroyed with destroy()
     171        template <class T>
     172        class SharedCounterImpl : public SharedCounter
     173        {
     174            public:
     175                SharedCounterImpl(T* pointer) : pointer_(pointer) {}
     176
     177                void destroy()
     178                {
     179                    delete this->pointer_;
     180                }
     181
     182            private:
     183                T* pointer_;
     184        };
     185
     186        _UtilExport SmallObjectAllocator& createSharedCounterPool();
     187
     188        FORCEINLINE SmallObjectAllocator& getSharedCounterPool()
     189        {
     190            static SmallObjectAllocator& instance = createSharedCounterPool();
     191            return instance;
     192        }
    71193    }
    72194
     195    /**
     196        @brief The SharedPtr template is a utility to manage pointers to an object.
     197        @param T The type of the managed object
     198
     199        SharedPtr acts like a real pointer, except that it keeps track of the number of
     200        references to the object. If the the number of references drops to zero, the
     201        object is destroyed automatically.
     202
     203        @see See @ref SharedPtrExample "this description" for some examples and more information.
     204
     205        @note The number of references is stored in a separate object that is shared
     206        among all instances of SharedPtr that point to the same pointer. This object is
     207        also responsible for destroying the pointer if the reference counter becomes zero.
     208    */
    73209    template <class T>
    74210    class SharedPtr
     
    78214
    79215        public:
     216            /// Default constructor, the pointer is set to NULL.
    80217            inline SharedPtr() : pointer_(0), counter_(0)
    81218            {
    82219            }
    83220
     221            /// Constructor, creates a SharedPtr that points to @a pointer, increments the counter.
    84222            inline SharedPtr(T* pointer) : pointer_(pointer), counter_(0)
    85223            {
    86224                if (this->pointer_)
    87225                {
    88                     void* chunk = getSharedCounterPool().alloc();
    89                     this->counter_ = new (chunk) SharedCounterImpl<T>(this->pointer_);
     226                    void* chunk = detail::getSharedCounterPool().alloc();
     227                    this->counter_ = new (chunk) detail::SharedCounterImpl<T>(this->pointer_);
    90228                }
    91229            }
    92230
     231            /// Copy-constructor, this SharedPtr now points to the same object like the other SharedPtr, increments the counter.
    93232            inline SharedPtr(const SharedPtr& other) : pointer_(other.pointer_), counter_(other.counter_)
    94233            {
     
    97236            }
    98237
     238            /// Copy-constructor for SharedPtr with another template agument, increments the counter.
    99239            template <class O>
    100240            inline SharedPtr(const SharedPtr<O>& other) : pointer_(other.pointer_), counter_(other.counter_)
     
    104244            }
    105245
     246            /// Destructor, decrements the counter and deletes the object if the counter becomes zero.
    106247            inline ~SharedPtr()
    107248            {
     
    113254                    {
    114255                        this->counter_->destroy();
    115                         getSharedCounterPool().free(this->counter_);
     256                        detail::getSharedCounterPool().free(this->counter_);
    116257                    }
    117258                }
    118259            }
    119260
     261            /// Assigns a new object, decrements the counter of the old object, increments the counter of the new object.
    120262            inline SharedPtr& operator=(const SharedPtr& other)
    121263            {
     
    124266            }
    125267
     268            /// Assigns a new object with another template argument, decrements the counter of the old object, increments the counter of the new object.
    126269            template <class O>
    127270            inline SharedPtr& operator=(const SharedPtr<O>& other)
     
    131274            }
    132275
     276            /// Casts the pointer to another type
    133277            template <class O>
    134278            inline SharedPtr<O> cast() const
     
    138282            }
    139283
     284            /// Overloaded -> operator, returns the pointer to the managed object.
    140285            inline T* operator->() const
    141286            {
     
    144289            }
    145290
     291            /// Overloaded * operator, returns a reference ot the managed object.
    146292            inline T& operator*() const
    147293            {
     
    150296            }
    151297
     298            /// Returns the pointer to the managed object.
    152299            inline T* get() const
    153300            {
     
    155302            }
    156303
     304            /// Returns true if the pointer is not NULL.
    157305            inline operator bool() const
    158306            {
     
    160308            }
    161309
     310            /// Swaps the pointer and the counter of two instances of SharedPtr with the same template argument.
    162311            inline void swap(SharedPtr& other)
    163312            {
     
    167316
    168317        private:
    169             inline SharedPtr(T* pointer, SharedCounter* counter) : pointer_(pointer), counter_(counter)
     318            /// Private constructor, used by the cast() function.
     319            inline SharedPtr(T* pointer, detail::SharedCounter* counter) : pointer_(pointer), counter_(counter)
    170320            {
    171321                if (this->pointer_)
     
    173323            }
    174324
    175             T* pointer_;
    176             SharedCounter* counter_;
     325            T* pointer_;                        ///< A pointer to the managed object of type @a T
     326            detail::SharedCounter* counter_;    ///< A pointer to the shared reference counter
    177327    };
    178328
     329    /**
     330        @brief A child class of SharedPtr, used to reflect the hierarchy of the underlying class @a T.
     331        @param T The type of the managed object
     332        @param Parent The type of the SharedPtr that manages the parent class of @a T
     333
     334        This class is used to reflect the hierarchy of the underlying class @a T.
     335        For example the @c Functor classes: While a @c Functor* pointer would be managed by
     336        @c SharedPtr<Functor>, the child class @c FunctorStatic is managed by the class
     337        <tt>SharedChildPtr<FunctorStatic, SharedPtr<Functor> ></tt>.
     338
     339        The second template argument @a Parent is used as the parent class of
     340        SharedChildPtr. This means that each instance of <tt>SharedChildPtr<T, Parent></tt>
     341        can be upcasted to @c Parent.
     342
     343        So for example this works:
     344        @code
     345        SharedChildPtr<FunctorStatic, SharedPtr<Functor> > functorStatic = createFunctor(&MyClass::myStaticFunction);
     346        SharedPtr<Functor> functor = functorStatic;
     347        @endcode
     348
     349        @note There are some typedefs and more to make the usage of SharedChildPtr easier
     350        for the classes Functor and Executor. See FunctorPtr.h and ExecutorPtr.h. The above
     351        example could thus be simplified the following way:
     352        @code
     353        FunctorStaticPtr functorStatic = createFunctor(&MyClass::myStaticFunction);
     354        FunctorPtr functor = functorStatic;
     355        @endcode
     356
     357        @see See SharedPtr for more information about the base class SharedPtr.
     358        @see See @ref SharedPtrExample "this description" for some examples about how to use SharedPtr.
     359    */
    179360    template <class T, class Parent>
    180361    class SharedChildPtr : public Parent
Note: See TracChangeset for help on using the changeset viewer.