内部から非静的メンバーにアクセスする必要がある場合は、その引数を適切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();
最後のラッパーが寿命を迎えると、すべてのラッパー間で明示的に共有されているハンドルが破棄されます。