【问题标题】:How do deal with noncopyable members in conjunction with named constructors?如何与命名构造函数一起处理不可复制的成员?
【发布时间】:2013-09-14 23:54:00
【问题描述】:

背景

我有一段代码具有以下特点:

  1. IO 类由于 std::ifstream 成员而不可复制
  2. Foo 具有 NamedConstructor 的类,喜欢调用复制构造函数

问题

有没有一种模式可以让我将 NamedConstructor 保存在 Foo(或类似的东西)中,但我仍然可以将不可复制的成员插入到 Foo 中?

我欢迎 C++11 功能/解决方案。

测试代码

#include <fstream>

class IO
{
        std::ifstream  m_ifs;  // due to this instance, IO is not copyable
};

// #define NEXT_LINE_REQUIRES_IO_MC

class Foo
{
#ifdef NEXT_LINE_REQUIRES_IO_MC
        IO  m_io;
#endif

public:
        static Foo NamedConstructor() {
                return Foo();
        }
private:
        Foo() { }
};

int
main( int argv, char* argc[] )
{
        Foo f = Foo::NamedConstructor();
}

【问题讨论】:

  • 你考虑过使用一些智能指针吗?
  • 你所拥有的应该在 C++11 中编译得很好,因为ifstream 是可移动的,因此IO 也应该是。但是,我只是用 MinGW (gcc 4.8) 对其进行了测试,它显然没有编译,抱怨删除了移动构造函数。如果你有同样的问题,这是一个错误。
  • @BenjaminLindley 废话 - 我认为你是对的,根据之前的帖子:stackoverflow.com/a/4846927/975129 fwiw,我使用的是 gcc 4.7.3
  • @kfmfe04:在此期间,您可能应该接受 Basile 的建议,并使用 unique_ptr&lt;ifstream&gt;
  • @BenjaminLindley ty,我会试试的。顺便说一句,编译器生成的移动构造函数应该在上面的 sn-p 中给我正确的行为,对吧?由于 NamedConstructor 的 rhs 无论如何都会消失(甚至可能通过 RVO),我认为我是安全的。 (我根本没有玩过移动构造函数......)

标签: c++ c++11


【解决方案1】:

这里不调用C++11中的copy构造函数,而是调用move构造函数,这样就ok了:

  • std::ifstream 在 C++11 中是可移动的
  • IO 因此将有一个有效的编译器生成的移动构造函数
  • 由于您没有为 Foo 声明复制构造函数或移动构造函数,因此它也会有一个有效的编译器生成 move.constructor。
  • Foo::NamedConstructor 中的 return 语句将调用 Foo 的移动构造函数,而不是复制构造函数

但是,您的测试代码(#ifdef 已注释掉)尚未在 gcc 4.8 上编译,因为它想使用已删除的 std::ifstream(std::ifstream&amp;)。这是由于 gcc 中的标准库尚未完全实现(参见 here)。

【讨论】:

  • 感谢您查看此内容,但如果您在#define NEXT_LINE_CAUSES_CC_OF_IO 中发表评论,构建将失败。
  • 对不起,那一个让我滑倒了。我查看了它并编辑了我的答案。
猜你喜欢
  • 1970-01-01
  • 2013-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多