首页 > 解决方案 > 从临时构造对象

问题描述

我正在使用带有(仅)构造函数的第三方类,如下所示

class foo  // cannot be altered
{
  public:
    explicit foo(std::istream&);
  ...
};

并且其中的文档建议采用以下方法

std::ifstream from("file.txt");
foo obj(from);
from.close();

我无法更改foo并想用作另一个班级的成员

class bar
{
     foo obj;                           // must not be altered
   public:
     explicit
     bar(std::string const&filename)    // must not be altered
       : obj(std::ifstream(filename))   // error: no matching constructor
   {}
   ...
};

除了这不起作用,因为不能保证std::ifstream从 the 创建的临时对象的filename寿命足够长以构造 the foo obj,因此不能转换为 a (如果接受 a std::istream&,情况会有所不同)。foo::foo()const std::istream&

所以我的问题是:我可以在bar不改变设计的情况下使构造函数工作bar(例如,bar::bar()采用 astd::istream&或 bar 来保存 astd::unique_ptr<foo>而不是 afoo或通过向 中添加数据成员bar)?

标签: c++constructortemporary-objectsobject-construction

解决方案


您的设计约束是不可能满足的。最安全的放松方法是坚持std::ifstreambar

class bar
{
     std::ifstream objs_stream;         // must be declared before obj
     foo obj;                           // must not be altered
   public:
     explicit
     bar(std::string const&filename)    // must not be altered
       : objs_stream(filename), obj(objs_stream)
   {}
   ...
};

另一种选择是向第三方类提交补丁:

class foo
{
  public:
    explicit foo(std::istream&);
    explicit foo(std::istream&& is) : foo(is) {}
  ...
};

如果foo有一个复制或移动构造函数,你可以

foo make_foo(const std::string& filename)
{
    std::ifstream is(filename);
    return foo(is);
}

class bar
{
     foo obj;                           // must not be altered
   public:
     explicit
     bar(std::string const&filename)    // must not be altered
       : obj(make_foo(filename))
   {}
   ...
};

推荐阅读