2010-08-12 58 views
3

考慮我有以下struct綁定兩個參數

struct IDirect3D 
{ 
    IDirect3D() : ref_count_(0) {} 
    unsigned long Release() { return --ref_count_; } 
private: 
    long ref_count_; 
    ~IDirect3D() {} 
}; 

我想在被跟隨的代碼(小例子)使用shared_ptr之如:

int main() 
{ 
    boost::shared_ptr<IDirect3D> ptr; 

    IDirect3D* p = 0; // initialized somewhere 
    ptr.reset(p, boost::mem_fn(&IDirect3D::Release)); 

    return 0; 
} 

這在大多數情況下,OK ,但如果p等於0,則會產生爆炸。我有以下缺失者,我想用:

template<typename T, typename D> 
inline void SafeDeleter(T*& p, D d) 
{ 
    if (p != NULL) { 
     (p->*d)(); 
     p = NULL; 
    } 
} 

但下面的代碼給出了很多錯誤的(貌似轉儲整個bind.hpp):

ptr.reset(p, boost::bind(SafeDeleter, _1, &IDirect3D::Release)); 

出了什麼問題我使用的bind

回答

5

Release()來自IUnknown - 那麼爲什麼不直接使用:

void my_deleter(IUnknown* p) { 
    // ... 
} 

ptr.reset(p, &my_deleter); 

注意,升壓也有一個intrusive_ptr這似乎更自然的位置:

void intrusive_ptr_add_ref(IUnknown* p) { p->AddRef(); } 
void intrusive_ptr_release(IUnknown* p) { p->Release(); } 

boost::intrusive_ptr<IDirect3D> d3d(...); 
IDirect3D* p = 0; 
d3d.reset(p); 

您的實際問題是,可能是有一個非模板函數SafeDeleter - 要專門使用模板函數,您必須使用類似於:

ptr.reset(p, boost::bind(&SafeDeleter<IDirect3D, ULONG (IDirect3D::*)()>, 
         _1, &IDirect3D::Release)); 
+0

感謝您的回答。但帶有'bind'的表達式在模板參數上看起來很糟糕。更好的是,我只會寫我自己的刪除器,它將調用'Release'。 – 2010-08-12 08:04:56

+0

@Kirill:根據[記錄的效果](http://boost.org/doc/libs/1_43_0/libs/smart_ptr/intrusive_ptr.html#Members)of ctor/dtor /'reset()'我沒有看看爲什麼這個檢查是必要的。 *(抱歉未定的來回滾動)* – 2010-08-13 20:17:47

+0

是的,你是對的。我混淆了'shared_ptr'。 – 2010-08-14 07:19:04