Created
March 19, 2012 15:45
-
-
Save egtra/2116775 to your computer and use it in GitHub Desktop.
コンストラクタでもshared_from_thisが使えるenable_shared_from_thisの製作
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| #include <memory> | |
| #include <boost/optional.hpp> | |
| #include <boost/utility/in_place_factory.hpp> | |
| template<typename T> | |
| class x_enable_shared_from_this | |
| { | |
| public: | |
| std::shared_ptr<T> shared_from_this() | |
| { | |
| return std::shared_ptr<T>(pWeakThis); | |
| } | |
| std::shared_ptr<T const> shared_from_this() const | |
| { | |
| return std::shared_ptr<T const>(pWeakThis); | |
| } | |
| protected: | |
| x_enable_shared_from_this() {} | |
| explicit x_enable_shared_from_this(std::shared_ptr<T> const& pThis) | |
| : pWeakThis(pThis) | |
| { | |
| } | |
| x_enable_shared_from_this(x_enable_shared_from_this const&) {} | |
| x_enable_shared_from_this& operator =(x_enable_shared_from_this const&) | |
| { | |
| return *this; | |
| } | |
| ~x_enable_shared_from_this() = default; | |
| private: | |
| std::weak_ptr<T> pWeakThis; | |
| }; | |
| template<typename T> | |
| class x_enable_shared_from_this_impl : public T | |
| { | |
| public: | |
| template<typename... Args> | |
| x_enable_shared_from_this_impl(std::shared_ptr<void> pThis, Args&&... args) | |
| : x_enable_shared_from_this<T>(std::shared_ptr<T>(pThis, this)) | |
| , T(std::forward<Args>(args)...) | |
| { | |
| } | |
| ~x_enable_shared_from_this_impl() = default; | |
| x_enable_shared_from_this_impl(x_enable_shared_from_this_impl const&) = delete; | |
| x_enable_shared_from_this_impl& operator =(x_enable_shared_from_this_impl const&) = delete; | |
| }; | |
| template<typename T, typename... Args> | |
| std::shared_ptr<T> x_make_shared(Args&&... args) | |
| { | |
| auto tmp = std::make_shared<boost::optional<x_enable_shared_from_this_impl<T>>>(); | |
| *tmp = boost::in_place(tmp, std::forward<Args>(args)...); | |
| return {tmp, tmp->get_ptr()}; | |
| } | |
| class Hoge : public virtual x_enable_shared_from_this<Hoge> | |
| { | |
| public: | |
| Hoge(int x, int y, int z) | |
| { | |
| auto p = shared_from_this(); | |
| std::cout << p << '\n'; | |
| std::cout << this << '\n'; | |
| std::cout << x << ' ' << y << ' ' << z << std::endl; | |
| } | |
| ~Hoge() {} | |
| }; | |
| int main() | |
| { | |
| auto p = x_make_shared<Hoge>(1, 2, 3); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment