マルチスレッド・プログラミングで、継承されたオブジェクトの破棄タイミングが難しく、enable_shared_from_this を使う事にした。
ただ、共通インタフェイスを持たせたくて継承させたので、素のままの enable_shared_from_this では不味そうなので、正しく動作させるための用法を忘備録として書き留める事にした。
#include <iostream>
#include <cassert>
#include <memory>
class Base : public std::enable_shared_from_this<Base> {
protected:
template <typename T>
std::shared_ptr<T> shared_from(T* derived) {
assert(this == derived);
return std::static_pointer_cast<T>(shared_from_this());
}
int n_;
public:
Base(int n) : n_(n) { std::cout << "Base()" << std::endl; }
virtual ~Base() { std::cout << "~Base(" << n_ << ")" << std::endl; }
};
class Delived : public Base {
public:
auto shared_from_this() { return shared_from(this); }
Delived(int m) : Base(m) {
std::cout << "Delived()" << std::endl;
}
virtual ~Delived() {
std::cout << "~Delived()" << std::endl;
}
};
void main() {
std::shared_ptr<Base> test1;
{
{
auto pbase = std::make_shared<Base>(1);
auto pderived = std::make_shared<Delived>(2);
test1 = pbase->shared_from_this();
std::shared_ptr<Delived> test2 = pderived->shared_from_this();
}
std::cout << "end" << std::endl;
}
}
実行すると
Base() // pbase のコンストラクタ
Base() // pderived の Base コンストラクタ
Delived() // pderived のコンストラクタ
~Delived() // スコープを抜けて test2が破棄され pbaseの参照カウントが0になり破棄
~Base(2)
end // スコープを抜ける
~Base(1) // test1が破棄され pderivedの参照カウントが0になり破棄
0 件のコメント:
コメントを投稿