/***************************************************************************** * HSmartPtr.h ***************************************************************************** * * Project: HALCON/C++ * Description: Template class for smart pointers used by tools and tuples * * (c) 2010-2020 by MVTec Software GmbH * www.mvtec.com * ***************************************************************************** * * *****************************************************************************/ #ifndef HCPP_SMART_PTR_H #define HCPP_SMART_PTR_H class LIntExport HSmartPtrRef { public: HSmartPtrRef(); unsigned int GetCount() const {return mCount;} void addref() const; bool deref() const; protected: mutable unsigned int mCount; }; namespace HalconCpp { template class HSmartPtr { public: HSmartPtr(); HSmartPtr(T* ptr); HSmartPtr(HSmartPtr const & ptr); virtual ~HSmartPtr(); virtual HSmartPtr& operator=(HSmartPtr const & ptr); virtual HSmartPtr& operator=(T* ptr); T* operator->() const; T& operator*() const; T* Ref() const; operator T&() const; bool operator!() const; operator bool() const; bool operator==(const HSmartPtr& ptr) const; bool operator==(const T* ptr) const; bool operator!=(const HSmartPtr& ptr) const; bool operator!=(const T* ptr) const; void Reset(); protected: void deref(); void addref(); void reset(T* ptr=0); T* mPtr; }; template HSmartPtr::HSmartPtr() : mPtr(NULL) {} template HSmartPtr::HSmartPtr(T* ptr) : mPtr(ptr) { addref(); } template HSmartPtr::HSmartPtr(HSmartPtr const & ptr) : mPtr(ptr.mPtr) { addref(); } template HSmartPtr::~HSmartPtr() { deref(); } template HSmartPtr& HSmartPtr::operator=(HSmartPtr const & ptr) { if (mPtr != ptr.mPtr) reset(ptr.mPtr); return *this; } template HSmartPtr& HSmartPtr::operator=(T* ptr) { if (mPtr != ptr) reset(ptr); return *this; } template T* HSmartPtr::operator->() const { return mPtr; } template T& HSmartPtr::operator*() const { return *mPtr; } template T* HSmartPtr::Ref() const { return mPtr; } template HSmartPtr::operator T&() const { return *mPtr; } template bool HSmartPtr::operator!() const { return mPtr == NULL; } template HSmartPtr::operator bool() const { return mPtr != NULL; } template bool HSmartPtr::operator==(const HSmartPtr& ptr) const { return mPtr == ptr.mPtr; } template bool HSmartPtr::operator==(const T* ptr) const { return mPtr == ptr; } template bool HSmartPtr::operator!=(const HSmartPtr& ptr) const { return !operator==(ptr); } template bool HSmartPtr::operator!=(const T* ptr) const { return !operator==(ptr); } template void HSmartPtr::Reset() { deref(); } template void HSmartPtr::deref() { if (mPtr) { /* It is neccessary to invalidate the smart pointer before releasing the * refered object for avoiding that within the update handlers of the * deleted object the smart pointer is used again. * This can happen, e.g., if this smart pointer is member of an array. * ------------------------------------------------------------------- */ T* ptr = mPtr; mPtr = 0; if (ptr->deref()) delete ptr; } } template void HSmartPtr::addref() { if (mPtr) mPtr->addref(); } template void HSmartPtr::reset(T* ptr/*=0*/) { deref(); mPtr = ptr; addref(); } } #endif