2010-08-12 4 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; 
} 

Это хорошо работает в большинстве случаев , но повреждения, если p равным 0. У меня есть следующий Deleter, который я хочу использовать:

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'. –

+0

@ Kirill: Согласно [документальным эффектам] (http://boost.org/doc/libs/1_43_0/libs/smart_ptr/intrusive_ptr.html#Members) ctor/dtor/'reset()' i do not посмотрите, почему эта проверка необходима. * (извините за нерешительность назад и вперед) * –

+0

Да, вы правы. Я перепутал с 'shared_ptr'. –

Смежные вопросы