added possibility to pass a custom deleter function down to shared_ptr.
Note: actually all of this seems against the spirit of C++ (and OO in general). This is a do-it-yourself aproach which adds far to much complexity (accidental, not fundamental complexity). So I checked it in for the record, but will abandon this aproach and rely on overloading of operator new / delete if necessary (and when we really need it)
This commit is contained in:
parent
2b0ea4650b
commit
b11ac46b76
2 changed files with 39 additions and 9 deletions
|
|
@ -65,9 +65,13 @@ namespace cinelerra
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
SMP wrap (T* product) { return SMP (product); }
|
SMP wrap (T* product) { return SMP (product); }
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef SMP PType;
|
typedef SMP PType;
|
||||||
|
|
||||||
|
typedef void (*DelHandler) (T* victim); ///< custom deleter function
|
||||||
|
void setDelHandler (DelHandler) {}; ///< if non-standard deleting is necessary
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -99,6 +103,12 @@ namespace cinelerra
|
||||||
*/
|
*/
|
||||||
typename WR::PType operator() () { return wrap (new T ); }
|
typename WR::PType operator() () { return wrap (new T ); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** this custom deleter function can be used if the
|
||||||
|
* operator delete call needs to be in the current scope.
|
||||||
|
* @see RefcountPtr
|
||||||
|
*/
|
||||||
|
static void destroy (T* victim) { delete victim; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -110,26 +120,34 @@ namespace cinelerra
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* a frequently used instantiation of the Wrapper,
|
* a frequently used instantiation of the Wrapper,
|
||||||
* utilizingthe refcounting shared_ptr from Boost.
|
* utilizing the refcounting shared_ptr from Boost.
|
||||||
*/
|
*/
|
||||||
template<class T>
|
template<class T>
|
||||||
class Wrapper<T, shared_ptr<T> >
|
class Wrapper<T, shared_ptr<T> >
|
||||||
{
|
{
|
||||||
/** let the smart-ptr use the custom operator delete,
|
|
||||||
* which may be defined in our Allocator baseclass.
|
|
||||||
*/
|
|
||||||
static void destroy (T* victim) { delete victim; };
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
shared_ptr<T> wrap (T* product) { return shared_ptr<T> (product, &destroy ); }
|
shared_ptr<T> wrap (T* product) { return shared_ptr<T> (product, destroy_ ); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef shared_ptr<T> PType;
|
typedef shared_ptr<T> PType;
|
||||||
|
|
||||||
|
|
||||||
|
Wrapper () : destroy_(&stdDelete) { }
|
||||||
|
|
||||||
|
typedef void (*DelHandler) (T* victim); ///< custom deleter function
|
||||||
|
void setDelHandler (DelHandler d) { this->destroy_ = d; } ///< custom deleter used by shard_ptr
|
||||||
|
|
||||||
|
private:
|
||||||
|
DelHandler destroy_;
|
||||||
|
static void stdDelete (T* victim) { delete victim; }; ///< by default just delete objects normally
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shortcut: commonly used (partial) instantiation of the Factory,
|
* Shortcut: commonly used (partial) instantiation of the Factory,
|
||||||
* generating refcounting shared_ptr wrapped Objects.
|
* generating refcounting shared_ptr wrapped Objects. Built upon
|
||||||
|
* the corresponding special intstantiation of the Wrapper template.
|
||||||
*/
|
*/
|
||||||
template
|
template
|
||||||
< class T, // the product to be created
|
< class T, // the product to be created
|
||||||
|
|
@ -139,6 +157,12 @@ namespace cinelerra
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef shared_ptr<T> PType;
|
typedef shared_ptr<T> PType;
|
||||||
|
|
||||||
|
/** especially the shared_ptr will use Factory::destroy,
|
||||||
|
* so it is sufficient to make Factory a friend if the
|
||||||
|
* Target class to be produced has private ctor/dtors
|
||||||
|
*/
|
||||||
|
RefcountPtr() { setDelHandler(&this->destroy); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,8 +68,6 @@ namespace cinelerra
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// @todo: make it possible to have a private destructor
|
|
||||||
public:
|
|
||||||
~TargetObj() throw()
|
~TargetObj() throw()
|
||||||
{
|
{
|
||||||
delete heapData_;
|
delete heapData_;
|
||||||
|
|
@ -117,6 +115,14 @@ namespace cinelerra
|
||||||
* custom allocator or a special deleter function.
|
* custom allocator or a special deleter function.
|
||||||
*/
|
*/
|
||||||
PType operator() (uint param) { return wrap (new TargetObj(param) ); }
|
PType operator() (uint param) { return wrap (new TargetObj(param) ); }
|
||||||
|
|
||||||
|
ObjFactory () { setDelHandler(&destroy); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** define a custom deleter function, so the actual destrucor call
|
||||||
|
* happenes within the scope of ObjFactory, which is friend of TargetObj
|
||||||
|
*/
|
||||||
|
static void destroy (TargetObj* victim) { delete victim; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue