Overview
CAutoNativePtr is a managed template class that acts
as a smart pointer, and is handy for using native objects in managed code.
template
<
typename T
>
ref class CAutoNativePtr
Here, T is the native type that's wrapped. The class
manages a smart pointer, which will automatically free the native resource when
it falls out of scope or the containing managed object is finalized during
garbage collection. The copy constructors and assignment operators transfer
ownership, which means that only one CAutoNativePtr can
own a specific native object at any time (unless you write buggy code that
directly overrides this rule).
Using the class
Here's some sample code that shows how the class can be used.
class Native
{
public:
void F()
{
}
};
class Derived : public Native{};
void SomeFunc(Native){} void SomeOtherFunc(Native*){}
ref class Ref
{
CAutoNativePtr<Native> m_native; public:
Ref()
{
}
Ref(Native* pN) : m_native(pN) {
}
Ref(CAutoNativePtr<Native> pN) : m_native(pN)
{
}
void Change(Native* pNew)
{
m_native = pNew;
}
void Change(CAutoNativePtr<Native> pNew)
{
m_native = pNew;
}
void DoStuff()
{
if(!m_native) {
}
else
{
m_native->F(); SomeFunc(*m_native); SomeOtherFunc(m_native); }
}
bool DoComparisons(CAutoNativePtr<Native> a1,
CAutoNativePtr<Native> a2, CAutoNativePtr<Native> a3)
{
return (a1 == a2) && (a1 != a3);
}
void Close()
{
m_native.Destroy(); }
};
int main()
{
CAutoNativePtr<Derived> d1(new Derived);
CAutoNativePtr<Derived> d2(new Derived);
CAutoNativePtr<Native> n1(d1);
n1 = d2;
return 0;
}
Class Reference
Methods
CAutoNativePtr - The constructor
There are four overloads that you can use.
CAutoNativePtr()
CAutoNativePtr(T* t)
CAutoNativePtr(CAutoNativePtr<T>% an)
template<typename TDERIVED>
CAutoNativePtr(CAutoNativePtr<TDERIVED>% an)
The parameter-less constructor creates a CAutoNativePtr
that wraps a nullptr object of type T. The overload that takes a T* can be
used to wrap an existing pointer. Then, there are two copy constructor
overloads, where one of them is to copy construct from a CAutoNativePtr<T> (same type) and the other is to copy
construct from a CAutoNativePtr<TDERIVED> (which
wraps a derived type of T). When you copy construct a
CAutoNativePtr object, the source object's T* is detached, because only one CAutoNativePtr should own a T* at any
given time, else we end up with double deletion.
~CAutoNativePtr/!CAutoNativePtr - Destructor and Finalizer
!CAutoNativePtr()
~CAutoNativePtr()
The allocated object (if any) is freed. By having the destructor invoke the
finalizer, both stack semantics and non-deterministic garbage collection are
supported.
Attach - To take over an existing T*
The CAutoNativePtr will take ownership of the T*, and if there's an existing T*, it
will be deleted.
Detach - Release the T*
The underlying T* is released, and it's up to the
caller to free the object now.
Destroy - Delete the underlying T*
The underlying T* is deleted. Once you make this call,
the CAutoNativePtr does not own any object any more.
Operators
operator-> - Pointer to member operator
static T* operator->(CAutoNativePtr<T>% an)
This returns the underlying T* object and allows the
user to access T methods and fields by using the -> operator.
operator T* - Cast to T*
static operator T*(CAutoNativePtr<T>% an)
This is a cast to the underlying T*. This means you
can pass a CAutoNativePtr object where a T* is expected, which is pretty convenient.
operator= - Assignment operator
There are three overloads for the assignment operator.
CAutoNativePtr<T>% operator=(T* t)
CAutoNativePtr<T>% operator=(CAutoNativePtr<T>%
an)
template<typename TDERIVED> CAutoNativePtr<T>%
operator=(CAutoNativePtr<TDERIVED>% an)
The first one takes a T*. If the CAutoNativePtr currently owns a T*,
that's released before ownership of the new T* is taken.
The other two overloads are for assignment from CAutoNativePtr objects, where one of them is specialized to
handle a CAutoNativePtr object that owns a T derived object. When ownership is taken, it's transferred,
which means the source objects loses ownership of the T*,
and this is done to avoid double-deletion.
History
- January 19th, 2006 : Article and code first published