Skip to content

Instantly share code, notes, and snippets.

@nekko1119
Last active December 19, 2015 12:29
Show Gist options
  • Save nekko1119/5955721 to your computer and use it in GitHub Desktop.
Save nekko1119/5955721 to your computer and use it in GitHub Desktop.
enable_shared_from_thisを継承したクラスのshared_ptrが作成された時に、enable_shared_from_thisのprivateデータメンバであるweak_ptrがどのようにしてthisで初期化されているのか、イメージを簡略的に書いてみた。スマートポインタとしての機能は無いです。
#include <iostream>
#include <cassert>
using std::cout;
template <class T>
class weak_ptr;
template <class T>
class enable_shared_from_this;
template <class T, class U>
void enable_shared(T* ptr, enable_shared_from_this<U>* shared_)
{
if (shared_)
{
shared_->wptr_.reset(ptr);
}
}
void enable_shared(...)
{
}
template <class T>
class shared_ptr
{
public:
shared_ptr()
: ptr_(nullptr)
{
enable_shared(ptr_, ptr_);
}
shared_ptr(T* ptr)
: ptr_(ptr)
{
enable_shared(ptr_, ptr_);
}
template <class U>
shared_ptr(const weak_ptr<U>& wptr)
: ptr_(wptr.ptr_)
{
}
T* get() const
{
return ptr_;
}
private:
T* ptr_;
};
template <class T>
class weak_ptr
{
public:
weak_ptr()
: ptr_(nullptr)
{
}
template <class U>
weak_ptr(const shared_ptr<U>& sp)
: ptr_(sp.get())
{
}
template <class U>
void reset(U* uptr)
{
ptr_ = uptr;
}
private:
T* ptr_;
template <class U>
friend class shared_ptr;
};
template <class T>
class enable_shared_from_this
{
public:
enable_shared_from_this() {}
~enable_shared_from_this() {}
shared_ptr<T> shared_from_this()
{
return shared_ptr<T>(wptr_);
}
private:
weak_ptr<T> wptr_;
template <class U, class V>
friend void enable_shared(U* ptr, enable_shared_from_this<V>* shared_);
};
class hoge
: public enable_shared_from_this<hoge>
{
public:
hoge()
{
cout << "hoge ctor\n";
}
~hoge()
{
cout << "hoge dtor\n";
}
shared_ptr<hoge> get_shared_ptr()
{
shared_ptr<hoge> sp = shared_from_this();
assert(this == sp.get());
return sp;
}
};
class foo
{
public:
foo()
{
cout << "foo ctor\n";
}
~foo()
{
cout << "foo dtor\n";
}
};
int main()
{
shared_ptr<hoge> h1(new hoge());
shared_ptr<hoge> h2(h1.get()->get_shared_ptr());
assert(h1.get() == h2.get());
shared_ptr<foo> f1(new foo());
delete h1.get();
delete f1.get();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment