【问题标题】:How to initialize object's manager w/o initializing object in shared_ptr?如何在 shared_ptr 中不初始化对象的情况下初始化对象的管理器?
【发布时间】:2016-02-15 16:13:00
【问题描述】:

我想以这种方式使用智能指针:

using namespace std;

shared_ptr<string> foo;
weak_ptr<string> bar (foo);
foo = make_shared<string>("some string");
cout << *bar.lock(); // SIGSEGV

线索是如何在不构造对象的情况下初始化shared_ptr 的对象管理器(本例中为string)。甚至可能吗?我可以使用对象的默认 ctor,然后使用复制/移动分配。但是可能存在一些更优雅的解决方案吗?

对我来说,对象不会被初始化是值得的——如果我用空值初始化 shared_ptr,那将是逻辑上的谎言。

【问题讨论】:

    标签: c++ shared-ptr smart-pointers weak-ptr


    【解决方案1】:

    为什么不这样做呢:

    shared_ptr<string> foo = make_shared<string>();
    weak_ptr<string> bar (foo);
    *foo = "some string":
    

    这样你实际上是在共享一个字符串。你描述的更像是共享一个共享指针。

    【讨论】:

    • 我知道这种可能性 :) 但对我来说,对象不会被初始化是值得的 - 我在一个大程序中使用它,如果我设法只创建它对我来说是完美的对象管理器,但不是对象。
    • @user3545806 嗯,我应该用一些嵌套指针搜索解决方案吗?我的意思是:shared_ptr&lt;unique_ptr&lt;string&gt;&gt;
    • 很抱歉回答了其他问题。
    • @KerrekSB 好的,谢谢。我也在考虑一些额外的延迟初始化类。我会检查代码,哪个解决方案是最好的,然后发布。
    【解决方案2】:

    我解决了我的问题。这个想法的核心是使用嵌套指针:shared_ptr&lt;unique_ptr&lt;MYTYPE&gt;&gt;。就我而言,我创建了一个包装模板:

    template<typename T>
    class LazyInitializator : public std::unique_ptr<T> {
    public:
        LazyInitializator() : std::unique_ptr<T>() {} // this ctor offers lazy initialization
        LazyInitializator(const T& val) : std::unique_ptr<T> (std::make_unique<T>(val)) {} // for normal construction
        LazyInitializator& operator= (const T& val) { 
            if (!std::unique_ptr<T>::operator bool()) // if object wasn't constructed
                std::unique_ptr<T>::operator= (std::make_unique<T>(val)); // construct it
            **this = val; // use assingment op provided by T - no unneccessary mem allocation
            return *this;
        }
    };
    

    多亏了它,我可以更轻松地使用shared_ptrs。我可以这样做:

    using namespace std;
    
    shared_ptr<LazyInitializator<string>> foo = make_shared<LazyInitializator<string>>();
    weak_ptr<LazyInitializator<string>> bar (foo);
    *foo = "some string";
    cout << **bar.lock();
    

    是的,我知道,看起来有点棘手,但这是我现在最好的解决方案。

    【讨论】:

      猜你喜欢
      • 2013-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多