AutoPtr< Type, DestructorPolicy > Class Template Reference

This reference page is linked to from the following overview topics: Incremental Improvements, Plug-in Upgrade Guide, Smart Pointers (AutoPtr).



Detailed Description

template<typename Type, typename DestructorPolicy = SinglePointerDestructor<Type>>
class MaxSDK::AutoPtr< Type, DestructorPolicy >

Automatic memory-ownership pointer supporting "resource acquisition is initialization.

"

This is a standardized implementation of std::auto_ptr from the STL, allowing us to portably include AutoPtrs in the 3ds Max SDK without forcing a compiler or runtime dll version on third-party developers. std::auto_ptrs are described in your favourite STL documentation, in Scott Meyers's More Effective C++ and on pp. 367-368 in Bjarne Stroustrup's The C++ Programming Language. This implementation is based on Stroustrup and Meyers.

AutoPtrs grant the same mechanics as a regular pointer, so they can be created, assigned and dereferenced much in the same way as a plain old pointer. Additionally, AutoPtrs provide "resource acquisition is initialization" and automatic memory ownership management in two ways:

  1. The object pointed to by the AutoPtr will be implicitly deleted when the AutoPtr goes out of scope
  2. Through "destructive copying" that causes a copied AutoPtr to surrender ownership to the pointed to object.

This is a very useful technique for making the ownership semantics of a function very clear. A function that takes an AutoPtr to an object as a parameter is stating that it assumes ownership of the pointed to object and that the caller must surrender ownership. A function that returns an AutoPtr states that the caller must assume ownership of the pointed-to object.

AutoPtrs help prevent memory leaks and lead to exception safe code by guaranteeing that dynamically allocated objects will be deleted when the AutoPtr goes out of scope. The following is unsafe code:

 void foo()
 {
    A *a = new A();
    // ...
    delete a;
 }

Will leak if any exception is thrown in the "..." part. Replacing with an AutoPtr guarantees that the memory is cleaned up, since leaving the function through an exception will cause the AutoPtr to go out of scope.

 void foo()
 {
    AutoPtr a(new A());
    // ...
 }

Since not all objects have the same destruction requirements, the AutoPtr template can be parameterized to support creating various types of AutoPtrs differentiated by their DestructorPolicy. Three standard forms, the default AutoPtr<Type>, ArrayAutoPtr<Type>, and DeleteThisAutoPtr<Type&gt are available. AutoPtr's default destructor policy is for use with a pointer pointing to a single object (one that uses new and delete). ArrayAutoPtr is for use with a pointer pointing to an array (one that uses new [] and delete []). DeleteThisAutoPtr is for use with Max types requiring clean up through a DeleteThis method.

The two standard implementations are probably enough to cover most cases. Other derivations would be used for, say, pointers using malloc and free or to hide the destructor implementation details by using an explicitly typed, non-templated DestructorPolicy to avoid having to inline the Delete method. This is necessary to implement explicit template instantiation for a forward declared type. The standard templates can't be explicitly instantiated on a forward declared type since they require that the destructor be defined.

NB: The destructive copy semantics mean that AutoPtrs are inappropriate for use in any of the STL's container classes. Classes with data members of type AutoPtr must be non-copyable (derive from class MaxSDK::Util::Noncopyable), or implement their own copy constructor and assignment operator where they deep-copy the object being owned by the AutoPtr.

NB2: Finally, be careful about passing AutoPtrs across DLL boundaries for DLLs compiled with different compilers or different memory allocation schemes. Objects traversing such boundaries must be deallocated on the same side as they were allocated. One way to guarantee this is to use it with objects derived from MaxHeapOperators, or to override a class's delete operator so that the code that actually frees the memory is on the correct side of the DLL boundary.

#include <autoptr.h>

List of all members.

Public Types

typedef Type  element_type
  Typedef to make the element type a member of the class.
typedef DestructorPolicy  destructor
  Typedef to make the DestructionPolicy type a member of the class.

Public Member Functions

  AutoPtr (Type *p=NULL)
  Construct, assuming ownership of the pointed-to object.
  ~AutoPtr ()
  Destructor - automatically cleans up the pointed-to object.
  AutoPtr (AutoPtr &a)
  Copy construct, assuming ownership from the source AutoPtr.
template<typename OtherType >
  AutoPtr (AutoPtr< OtherType, DestructorPolicy > &a)
  Conversion copy constructor.
AutoPtr operator= (AutoPtr &a)
  Assignment, takes over ownership from the source AutoPtr.
template<typename OtherType >
AutoPtr operator= (AutoPtr< OtherType, DestructorPolicy > &a)
  Conversion assignment, takes over ownership of any type assignable to type from the source AutoPtr.
Type &  operator* () const
  Dereferencing operator - works exactly like a plain pointer's operator*.
Type *  operator-> () const
  Pointer-to-member dereferencing operator - works exactly like a plain pointer's operator->.
Type *  Get () const
  Get the plain pointer back.
Type *  Release ()
  Relinquish ownership of the pointed-to object to the caller.
void  Reset (Type *p=NULL)
  Assume ownership of a new object, any existing pointer will be deleted.
bool  IsNull () const
  Addition to the textbook interface.
  AutoPtr (const AutoPtrRef< Type > &ref)
  Construct from an AutoPtrRef.
template<typename OtherType >
  operator AutoPtrRef< OtherType > ()
  Convert to an AutoPtrRef.
template<typename OtherType >
  operator AutoPtr< OtherType, DestructorPolicy > ()
  Destructive copy-convert allowing for cast of the pointer type.

Member Typedef Documentation

typedef Type element_type

Typedef to make the element type a member of the class.

typedef DestructorPolicy destructor

Typedef to make the DestructionPolicy type a member of the class.


Constructor & Destructor Documentation

~AutoPtr ( ) [inline]

Destructor - automatically cleans up the pointed-to object.

{ DestructorPolicy::Delete(mPtr); }
AutoPtr ( AutoPtr< Type, DestructorPolicy > &  a ) [inline]

Copy construct, assuming ownership from the source AutoPtr.

Parameters:
a Another AutoPtr. This newly constructed AutoPtr will take ownership of a's pointed-to object, and subsequently, a will point to NULL. AutoPtr a may no longer be used to access the pointed-to object after being copied.
: mPtr(a.Release()) {}
AutoPtr ( AutoPtr< OtherType, DestructorPolicy > &  a ) [inline]

Conversion copy constructor.

Assumes ownership of any type assignable to Type.

Parameters:
a Another AutoPtr. This newly constructed AutoPtr will take ownership of a's pointed-to object, and subsequently, a will point to NULL. AutoPtr a may no longer be used to access the pointed-to object after being copied.
                                                                                   : 
        mPtr(a.Release()) 
    {}
AutoPtr ( const AutoPtrRef< Type > &  ref ) [inline]

Construct from an AutoPtrRef.

This may be done implicitly or explicitly. The Ref object exists to avoid temporarily needing to have two AutoPtrs own the same object.

Parameters:
ref helper object.

Reimplemented in AutoPtr< Type >, AutoPtr< TPARotateTransformerImpl >, AutoPtr< ReferenceMakerImplData >, AutoPtr< ClassDirectoryImpl >, AutoPtr< AnimatableImplData >, AutoPtr< DependentEnumProcImplData >, AutoPtr< PathImpl >, AutoPtr< SubClassListImpl >, AutoPtr< RefEnumProcImplData >, AutoPtr< ClassEntryImpl >, AutoPtr< RemapDir >, and AutoPtr< MtlBaseImplData >.

: mPtr(ref.mPtr) {}

Member Function Documentation

AutoPtr& operator= ( AutoPtr< Type, DestructorPolicy > &  a ) [inline]

Assignment, takes over ownership from the source AutoPtr.

Any existing pointer in this AutoPtr will be deleted.

Parameters:
a Another AutoPtr. This newly constructed AutoPtr will take ownership of a's pointed-to object, and subsequently, a will point to NULL. AutoPtr a may no longer be used to access the pointed-to object after being copied.
    {
        if(Get() != a.Get())
        {
            DestructorPolicy::Delete(mPtr);
            mPtr = a.Release();
        }
        return *this;
    }
AutoPtr& operator= ( AutoPtr< OtherType, DestructorPolicy > &  a ) [inline]

Conversion assignment, takes over ownership of any type assignable to type from the source AutoPtr.

Any existing pointer in this AutoPtr will be deleted.

Parameters:
a Another AutoPtr. This newly constructed AutoPtr will take ownership of a's pointed-to object, and subsequently, a will point to NULL. AutoPtr a may no longer be used to access the pointed-to object after being copied.
    {
        if(Get() != a.Get())
        {
            DestructorPolicy::Delete(mPtr);
            mPtr = a.Release();
        }
        return *this;
    }
Type& operator* ( ) const [inline]

Dereferencing operator - works exactly like a plain pointer's operator*.

Returns:
A reference to the pointed-to object.
{ return *mPtr; }
Type* operator-> ( ) const [inline]

Pointer-to-member dereferencing operator - works exactly like a plain pointer's operator->.

Returns:
Pointer to member.
{ return mPtr; }
Type* Get ( ) const [inline]

Get the plain pointer back.

This does not affect the ownership.

This AutoPtr will retain ownership of the pointer, the client must not delete the pointer.

Returns:
The contained, plain pointer.
{ return mPtr; }
Type* Release ( ) [inline]

Relinquish ownership of the pointed-to object to the caller.

After a call to release, this AutoPtr will no longer own the pointed-to object and will point to NULL. This AutoPtr may no longer be used to access the pointed-to object.

Returns:
the contained, plain pointer, for which the caller is now responsible.
    {
        Type *temp = mPtr;
        mPtr = NULL;
        return temp;
    }
void Reset ( Type *  p = NULL ) [inline]

Assume ownership of a new object, any existing pointer will be deleted.

Parameters:
p New pointer whose object this AutoPtr will now own.
    {
        if(p != mPtr)
        {
            DestructorPolicy::Delete(mPtr);
            mPtr = p;
        }
    }
bool IsNull ( ) const [inline]

Addition to the textbook interface.

Equivalent to get() == NULL.

Returns:
true if this AutoPtr points to NULL. False, otherwise.
{ return (NULL == mPtr); }
operator AutoPtrRef< OtherType > ( ) [inline]

Convert to an AutoPtrRef.

    {
        return AutoPtrRef<OtherType>(this->Release());
    }
operator AutoPtr< OtherType, DestructorPolicy > ( ) [inline]

Destructive copy-convert allowing for cast of the pointer type.

    {
        return AutoPtr<OtherType, DestructorPolicy>(this->Release());
    }