許多C API提供的是採取**p
其除了釋放資源也設置指針NULL
發佈功能。
我想換用一個定製刪除一個boost::shared_ptr
例如C API調用。定製刪除了那個的shared_ptr指針預計的地址
下面是有關ffmpeg的一個例子:
AVFrame* frame = av_frame_alloc(); // allocate resource
// Do stuff with frame
av_frame_free(&frame) // free resource
要利用RAII,我可以像這樣重寫這個:
AVFrame* frame = av_frame_alloc();
boost::shared_ptr<AVFrame*> frame_releaser(&frame, av_frame_free);
// Do stuff with frame
注意,shared_ptr<>
是<AVFrame*>
型的,而不是<AVFrame>
爲指針類型。
這種方法要求我保存資源,並分別在釋放器,它有幾個缺點:
frame
也可以從外部改變導致泄漏。- 它需要2變量,而不是一個,這使得代碼更容易發生錯誤。
我想使用一個單一的shared_ptr
變量都需要的時候保持資源和釋放它。
在boost::ref
精神,我期待寫或使用通用address_of_arg_wrapper
的缺失者,讓我寫的財產以後這樣的:
boost::shared_ptr<AVFrame> frame_handle(av_frame_alloc(), address_of_arg_wrapper(av_frame_free));
// Do stuff with frame_handle.get()
或
boost::shared_ptr<AVFrame> frame_handle(av_frame_alloc(), address_of_arg_wrapper<av_frame_free>());
// Do stuff with frame_handle.get()
包裝是通用的並且接受任何指針(ref)類型,這一點很重要,所以它可以用於任何這樣的API函數。
我也不想指定類型。
Boost有這樣的實用程序嗎?
如果沒有,那麼如何寫一個這樣的通用函子呢?
編輯 - 解決方案的完整性:
該解決方案是基於@R. Martinho Fernandes's answer below。
- 它包含一個模板函數來創建模板函子,因此不需要指定模板類型。
- 代碼取決於
boost::decay
。一個僅包含Fun fun;
成員的版本也適用於我測試的簡單案例。 - 我將名稱更改爲
arg_ref_adaptor()
。歡迎更好的名稱建議!
下面的代碼:
#include <boost\type_traits\decay.hpp>
//////////////////////////////////////////////////////////////////////////
// Given a function or callable type 'fun', returns an object with
// a void operator(P ptr) that calls fun(&ptr)
// Useful for passing C API function as deleters to shared_ptr<> which require ** instead of *.
template <typename Fun>
struct arg_ref_adaptor_functor
{
public:
arg_ref_adaptor_functor(Fun fun): fun(fun) {}
template <typename P>
void operator()(P ptr)
{ fun(&ptr); }
private:
typename boost::decay<Fun>::type fun;
};
template <typename Fun>
inline arg_ref_adaptor_functor<Fun> arg_ref_adaptor(Fun fun)
{ return arg_ref_adaptor_functor<Fun>(fun); }
用法:
boost::shared_ptr<AVFrame> frame_handle(::av_frame_alloc()
,arg_ref_adaptor(::av_frame_free));
// Do stuff with frame_handle.get()
// The resource will be released using ::av_frame_free() when frame_handle
// goes out of scope.
IMO應的typedef的boost :: shared_ptr的,因爲C++ 11有標準:: shared_ptr的,你會希望儘量減少升級編譯器時的遷移工作。 – Bathsheba
@Bathsheba我只會保持命名空間清晰。批量替換boost :: shared_ptr到std :: shared_ptr可以在一秒內完成。而混合命名空間是危險的。 – billz
@billz:很酷;只要我們考慮到移民問題。 – Bathsheba