如何在shared_ptr中初始化没有初始化对象的对象管理器?

时间:2016-02-15 16:13:00

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

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

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,那将是逻辑上的谎言。

2 个答案:

答案 0 :(得分:0)

为什么不这样做呢:

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

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

答案 1 :(得分:0)

我解决了我的问题。这个想法的核心是使用嵌套指针:shared_ptr<unique_ptr<MYTYPE>>。在我的例子中,我创建了一个包装模板:

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_ptr。我可以这样做:

using namespace std;

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

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