晚期非可复制成员初始化

时间:2015-10-16 23:42:22

标签: c++ c++11 boost

我正在尝试初始化无法分配或复制的对象成员。我需要先执行一些其他任务,初始化取决于它,所以我必须延迟它。

#include <boost/process.hpp>

class A{
    std::unique_ptr<boost::process::child> child_;
    std::unique_ptr<boost::process::pistream> is;

    A(std::string exec, boost::process::context process_context){
        // Stuff that needs to be done first
        // ...

        child_ = std::make_unique<boost::process::child>(start_child(exec, process_context));
        is = std::make_unique<boost::process::pistream>(child_->get_stdout()); // <- error

    }

    boost::process::child start_child(std::string exec, boost::process::context process_context);
};

我从中得到的错误是:

  

错误C2280:   “的std :: basic_ios&GT; :: basic_ios(常量   的std :: basic_ios&GT; &amp;)':试图   引用已删除的功能

如果我理解正确的话,那行中的某个地方就会发生一个副本,这是不允许的。 不需要唯一的指针。我只是使用它们来避免另一个错误(没有默认初始化)但我很乐意接受有或没有它们的建议。

2 个答案:

答案 0 :(得分:3)

您可以使用#include <memory> #include <boost/optional.hpp> struct pistream { }; struct child { pistream& get_stdout() { return is; } pistream is; }; struct context { }; class A { std::unique_ptr<child> child_; boost::optional<pistream&> is; A(std::string, context) { // Stuff that needs to be done first // ... child_ = std::make_unique<child>(); is = child_->get_stdout(); } }; 进行延迟初始化。

<强> Live On Coliru

{{1}}

答案 1 :(得分:3)

问题是std::unique_ptr想要pistream的所有权,因此它会尝试复制,因为您发现并不允许。如果您考虑一下,这是有道理的:您当然不希望std::unique_ptr<b::p::pistream>在其析构函数中删除_child的流。

最简单的解决方案是使用常规的非拥有指针,比如说:

class A{
    std::unique_ptr<boost::process::child> child_;
    boost::process::pistream* is = nullptr;

    A(std::string exec, boost::process::context process_context){
        // ...
        child_ = std::make_unique<boost::process::child>(start_child(exec, process_context));

        is = &child_->get_stdout();
    }
};

当然,您希望在实际使用之前检查is是否不是nullptr,但unique_ptr也是如此。