
.. _smartpointer-page:

##############
Smart Pointers 	
##############

|ProductName| uses intrusive reference counting in order to avoid duplication of data. All classes that 
derive from the :class:`RefCountedObject <cee::RefCountedObject>` are reference counted. You should 
never delete these objects, but do addRef() when you start using the object and release() when are finished 
with it. When the reference count of an object goes to zero, the object is deleted.

To make it easy to use reference counted object, we recommend using the smart pointer :class:`PtrRef <cee::PtrRef>`.
The :class:`PtrRef <cee::PtrRef>` template class that mimics, by means of operator overloading, 
the behavior of traditional (raw) pointers. You can manually handle reference counted objects by doing addRef() 
and release(), but we strongly recommend using :class:`PtrRef <cee::PtrRef>` as this is easier and less error-prone.

If you need a raw pointer from a PtrRef, use the :func:`get() <cee::PtrRef::get>` method.

When using smart pointers, you never have to think about deleting objects. The PtrRef will addRef() and object
when it is assigned to it, and release the object in the destructor. When used right, it mimics the 
garbage collection systems found in C# and Java, although it is more explicit and destruction happens 
immediately.

**Some tips regarding smart pointers in Envision:**

-   Never pass PtrRefs as arguments to a method. Pass the naked pointer.
-   Only return a PtrRef from a method/function if the class does not hold a reference. In |ProductName| we only
    return PtrRefs from factory methods/functions. If the method is not a factory method, return the naked pointer.
-   Avoid using pointers to PtrRef's. PtrRefs should be real members of your class and allocated on the stack when 
    used in a method/function.

