如果您需要从内部访问非静态成员,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();
最后一个过期的包装器将破坏句柄,该句柄在所有包装器之间显式共享。