/*============================================================================= Project: ManagedITK Program: Insight Segmentation & Registration Toolkit Module: itkManagedObjectAutoPtr.cxx Language: C++/CLI Author: Dan Mueller Date: $Date: 2007-09-01 06:17:25 +1000 (Sat, 01 Sep 2007) $ Revision: $Revision: 2 $ This file was based on the following article: "Best Practices for Writing Efficient and Reliable Code with C++/CLI" by Kenny Kerr (May 2006) http://msdn.microsoft.com/library/en-us/dnvs05/html/CplusCLIBP.asp Portions of this code are covered under the ITK and VTK copyright. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =============================================================================*/ #pragma once #pragma warning( disable : 4635 ) // Disable warnings about XML doc comments #ifndef __itkObjectAutoPtr_cxx #define __itkObjectAutoPtr_cxx using namespace System::Diagnostics; namespace itk { template ref struct itkObjectAutoPtr { private: T* m_ptr; bool m_disposed; public: itkObjectAutoPtr( ) : m_ptr( NULL ), m_disposed( false ) { } itkObjectAutoPtr( T* ptr ) : m_ptr( ptr ), m_disposed( false ) { if ( ptr != NULL ) ptr->Register( ); } itkObjectAutoPtr( itkObjectAutoPtr% right ) : m_ptr( right.Release() ), m_disposed( false ) { } //~itkObjectAutoPtr() //{ // if (!m_disposed) Reset(); // m_disposed = true; //} //!itkObjectAutoPtr() //{ // // Dispose of the managed pointer if the user forgot // if ( !m_Disposed ) // delete this; //} T* operator->( ) { return m_ptr; } T* Get( ) { return m_ptr; } T* Release( ) { T* released = m_ptr; m_ptr = NULL; return released; } void Reset( ) { Reset( NULL ); } void Reset(T* ptr) { try { if ( m_ptr != NULL && ptr != m_ptr ) { // Free the existing native pointer m_ptr->RemoveAllObservers( ); m_ptr->SetReferenceCount( 0 ); } // Set the new native pointer (sets to NULL if ptr = NULL) m_ptr = ptr; // Register the new pointer to keep it alive if ( m_ptr != NULL ) { m_ptr->Register( ); } } catch (...) { // HACK: Consume the exception, even though it is bad practice. // NOTE: This method tends to throw System.AccessViolationExceptions, // probably because the memory has been previously freed. } } }; } // end namespace itk #endif