この種の問題に対する解決策は、破棄前の段階であり、破棄がどのように発生するかを手動で制御できます。
パターンを使用してオブジェクトを実装しますpImpl
。ラッピング オブジェクトpImpl
を破棄する場合は、破棄する前に に破棄することを通知します。
pImpl
子メソッドがコールバックを登録できる基本virtual PreDestroyable
クラスを持つことができPreDestruction
ます。コールバックは、この破棄前のフェーズで呼び出します。
class Destroyable {
protected:
Destroyable() {}; // must be empty
virtual ~Destroyable() { Assert(PreDestroyers.empty()); };
void RegisterPreDestroy( std::function<void()> const& func ) { PreDestroyers.push_back(func) );
private:
std::vector<std::function<void()>> PreDestroyers;
public:
// reverse order, reentrant:
void PrepareToDie() {
while (!PreDestroyers.empty()) {
auto f = PreDestroyers.back();
PreDestroyers.pop_back();
f();
}
}
};
// handles registration:
template<typename T>
class HasPreDestroyCode: public virtual Destroyable {
// TODO: usual CRTP static or dynamic checks:
T* self() { return static_cast<T*>(this); }
T const* self() const { return static_cast<T*>(this); }
HasPreDestroyCode() {
RegisterPreDestroy( [&]() { self()->PreDestroy(); } );
}
HasPreDestroyCode( HasPreDestroyCode const& other ) {
RegisterPreDestroy( [&]() { self()->PreDestroy(); } );
}
HasPreDestroyCode( HasPreDestroyCode const& other ) {
RegisterPreDestroy( [&]() { self()->PreDestroy(); } );
}
private:
HasPreDestroyCode& operator=( HasPreDestroyCode const& other ) = delete;
};
class Test: HasPreDestroyCode<Test> {
public:
void PreDestroy() {}
};
私は C++11 より前にこのようなものを最後に書いたので、それを構築する移動を処理する方法を考え出していませんでした。そして、それはすべて実行時に行われますが、上記のようなことをより少ない実行時データで行うことはおそらく可能です。破棄前のコードなどを含む階層内の型のリストのようなものですか?