Main Page | Modules | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages

Ref Class Template Reference
[BaseBase]

Smart pointer class Smart pointers provide automatic memory management, so that programmer never cares on freeing memory. Smart pointers mechanism frees an object when there are no any references to it. Smart pointers should be used instead of standard C pointers:
  Object* obj; // standard pointer, should be deleted after use
  gml::Ref<Object> obj; // smart pointer frees memory when necessary
Attention:
Smart pointers works only with objects that support AddRef() and Release() operations. It is assumed that object keeps a reference count (a number of smapt pointers pointing to it). This reference count is incremented in AddRef() command and decremented in Release(). Also Release() performs check whether reference count is 0 and calls 'delete this'. GML provides special base class for this: gml::SmartObject. If you want to use smart pointers either derive your object from this class or provide own implementation of AddRef() and Release() methods. 1) initialization Smart pointers are initiliazed just like the standard pointers:
  gml::Ref<Object> obj =  new Object(1,2,3);

Smart pointers must never be defined like this: gml::Rev<Object>* obj; !!! 2) use of smart pointers Smart pointers are dereferenced like normal pointers:

  gml::Ref<Object> obj =  new Object(1,2,3);
  obj->SomeMethod();
  (*obj).SomeMethod();
3) smart pointers as parameters Smart pointers are implicitly casted to normal pointers:
  gml::Ref<Object> obj =  new Object(1,2,3);
  Object* obj1 =  obj;
This operation is dangerous unless used properly. You should use it like follows. Smart pointers may be passed to functions and returned from functions like normal pointers.
  ...
  Object* SomeMethod(Object* obj);
  ...
  gml::Ref<Object> obj =  new Object(1,2,3);
  gml::Ref<Object> obj1 = SomeMethod(obj);
The general rule is this: Use ONLY smart pointers when storing objects. Use normals pointers when passing smart pointers as parameters or return values So the following is forbidden:
  class SomeClass
    {
    private:
      Object* obj;
    public:
      void CreateObject()
        {
        gml::Ref<Object> obj = new Object(1,2,3);
        m_obj = obj;
        } // at this point obj will be deleted, and m_obj will be undefined!!
    };
Correct use:
  class SomeClass
    {
    private:
      gml::Ref<Object> obj;
    public:
      void CreateObject()
        {
        gml::Ref<Object> obj = new Object(1,2,3);
        m_obj = obj;
        } 
    };
.
More...

#include <gmlref.h>

List of all members.

Public Member Functions

 Ref (T *real_ptr=NULL)
 Default contructor.

 Ref (const Ref &rhs)
 Copy constructor.

 ~Ref ()
 Destructor.

Refoperator= (const Ref &rhs)
 Overloaded operator =.

T * operator-> () const
 Overloaded operator.

T & operator * () const
 Overloaded operator.

int IsSet () const
 Whether this pointer is not null.

 operator T * () const
 Implicit conversion to C pointer.

void Set (T *real_ptr)
 Forced assignment of C pointer to this reference
Attention:
Danger function, use it carefully.


void Clear ()
 Cleans this reference.


Related Functions

(Note that these are not member functions.)

Ref< newT > & ConvRef (const Ref< oldT > &old_ref)
 Casting & convertion of smart references.


Detailed Description

template<class T>
class gml::Ref< T >

Smart pointer class Smart pointers provide automatic memory management, so that programmer never cares on freeing memory. Smart pointers mechanism frees an object when there are no any references to it. Smart pointers should be used instead of standard C pointers:
  Object* obj; // standard pointer, should be deleted after use
  gml::Ref<Object> obj; // smart pointer frees memory when necessary
Attention:
Smart pointers works only with objects that support AddRef() and Release() operations. It is assumed that object keeps a reference count (a number of smapt pointers pointing to it). This reference count is incremented in AddRef() command and decremented in Release(). Also Release() performs check whether reference count is 0 and calls 'delete this'. GML provides special base class for this: gml::SmartObject. If you want to use smart pointers either derive your object from this class or provide own implementation of AddRef() and Release() methods. 1) initialization Smart pointers are initiliazed just like the standard pointers:
  gml::Ref<Object> obj =  new Object(1,2,3);

Smart pointers must never be defined like this: gml::Rev<Object>* obj; !!! 2) use of smart pointers Smart pointers are dereferenced like normal pointers:

  gml::Ref<Object> obj =  new Object(1,2,3);
  obj->SomeMethod();
  (*obj).SomeMethod();
3) smart pointers as parameters Smart pointers are implicitly casted to normal pointers:
  gml::Ref<Object> obj =  new Object(1,2,3);
  Object* obj1 =  obj;
This operation is dangerous unless used properly. You should use it like follows. Smart pointers may be passed to functions and returned from functions like normal pointers.
  ...
  Object* SomeMethod(Object* obj);
  ...
  gml::Ref<Object> obj =  new Object(1,2,3);
  gml::Ref<Object> obj1 = SomeMethod(obj);
The general rule is this: Use ONLY smart pointers when storing objects. Use normals pointers when passing smart pointers as parameters or return values So the following is forbidden:
  class SomeClass
    {
    private:
      Object* obj;
    public:
      void CreateObject()
        {
        gml::Ref<Object> obj = new Object(1,2,3);
        m_obj = obj;
        } // at this point obj will be deleted, and m_obj will be undefined!!
    };
Correct use:
  class SomeClass
    {
    private:
      gml::Ref<Object> obj;
    public:
      void CreateObject()
        {
        gml::Ref<Object> obj = new Object(1,2,3);
        m_obj = obj;
        } 
    };
.

Note:
Nevertheless, nobody restricts you from passing smart pointers as parameters and return values. Simple pointers are just have more natural interface. 4) casting of smart pointers Since smart pointers are implicitly casted to C pointers, casting rules are the same as for C pointers. The only issue appears when use need to cast from one smart pointer to another. In this case you need to use gml::ConvRef() operation:
  gml::Ref<BaseObject> b;
  gml::Ref<DerivedObject> c;
  c = b; // this may not work in compilers which nor support template casting methods
  c = gml::ConvRef<DerivedObject>(b); // OK
Attention:
This simple example not working (!) :
  Object* CreateObject()
    {
    gml::Ref<Object> obj = new Object;
    return obj; // at this point reference count of obj is 1, so the obj is deleted 
                // before returned from the function!
    }
Correct use is one of the following:
  Object* CreateObject()
    {
    Object* obj = new Object;
    return obj; 
    }
  gml::Ref<Object> CreateObject()
    {
    gml::Ref<Object> obj = new Object;
    return obj; 
    }
Warning:
It is forbidden to assign arrays created by new[] to smart pointers
  gml::Ref<Object> obj = new Object[10]; // result is undefined!!!!!

All smart object should be create by new operator! The following is strictly forbidden :

  Object obj;
  gml::Ref<Object> = &obj;


The documentation for this class was generated from the following file:
Generated on Tue Jan 13 21:12:02 2004 for Graphics and Media Lab CSL by doxygen 1.3.4