如果您需要从Close 中访问非静态成员,您需要正确绑定其this 参数
CWrapper() :
m_pHandle(new HANDLE, boost::bind(&CWrapper::Close, this, _1)) {
//code to open handle
}
然而,这包含一个隐藏的错误。您的对象是可复制的,并且您将删除器绑定到 *this 的对象。句柄与您创建的第一个包装器相关联,但如果您复制包装器,则该句柄是共享的,但与第一个包装器相关联,可能不再存在:
CWrapper getWrapper() { CWrapper w; return w; }
CWrapper x = getWrapper();
在执行该代码并且 x 将被销毁后,行为未定义,因为 x 对内部句柄指针的销毁将尝试使用绑定在 w 的构造函数调用中的对象 - 然而那个对象已经不存在了!
对此的解决方案是将与句柄关联的数据存储在分配的对象本身中,而不是尝试将其存储在顶级句柄对象中,如以下代码中所示
class CWrapper
{
public:
CWrapper():m_pHandle(new CHandle)
{ }
private:
// This class cannot be copied
class CHandle : boost::noncopyable {
friend class CWrapper;
CHandle()
:m_pHandle(new HANDLE) {
// code to open handle
}
~CHandle() {
// code to close this handle, making use of
// auxilary data for whatever reason
}
private:
boost::scoped_ptr<HANDLE> m_pHandle;
// auxilary data associated with the handle...
};
boost::shared_ptr<CHandle> m_pHandle;
};
辅助数据不再存储在句柄中,而是与包装器的所有副本共享的数据一起存储。共享数据本身是使用其正常的构造函数和析构函数创建和销毁的。
CWrapper getHandle() { return myHandle; }
CWrapper w = getHandle();
最后一个过期的包装器将破坏句柄,该句柄在所有包装器之间显式共享。