Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何结合命名构造函数处理不可复制成员?_C++_C++11 - Fatal编程技术网

C++ 如何结合命名构造函数处理不可复制成员?

C++ 如何结合命名构造函数处理不可复制成员?,c++,c++11,C++,C++11,背景 我有一段具有以下特征的代码: IO类,由于std::ifstream成员而不可复制 Foo类,它有一个NamedConstructor,它喜欢调用复制构造函数 问题 我是否可以使用一种模式,将NamedConstructor保存在Foo(或类似的东西)中,但仍然可以将不可复制的成员插入Foo 我欢迎C++11特性/解决方案 测试代码 #include <fstream> class IO { std::ifstream m_ifs; // due to t

背景

我有一段具有以下特征的代码:

  • IO
    类,由于
    std::ifstream
    成员而不可复制
  • 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();
    }
    
    #包括
    IO类
    {
    std::ifstream m_ifs;//由于此实例,IO不可复制
    };
    //#定义下一行(需要)
    福班
    {
    #ifdef下一行需要IO MC
    木卫一;
    #恩迪夫
    公众:
    静态Foo NamedConstructor(){
    返回Foo();
    }
    私人:
    Foo(){}
    };
    int
    main(int argv,char*argc[])
    {
    Foo f=Foo::NamedConstructor();
    }
    
    这在C++11中不调用复制构造函数,而是调用移动构造函数,这是正常的:

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

    但是,您的测试代码(注释掉了
    #ifdef
    )尚未在GCC4.8上编译,因为它希望使用已删除的
    std::ifstream(std::ifstream&)
    。这是由于GCC中尚未完全实现的标准库(参见)。< / P>您是否考虑使用一些智能指针?您在C++ 11中应该编译好的,因为<代码> IFSturi>代码是可移动的,因此<代码> IO < /代码>也应该是。然而,我只是用MinGW(gcc4.8)测试了它,它显然没有编译,抱怨删除了move构造函数。如果你有同样的问题,这是一个错误。@BenjaminLindley垃圾-我认为你是对的,根据前面的帖子:fwiw,我使用的是GCC4.7。3@kfmfe04:同时,你可能应该接受巴兹尔的建议,使用
    unique\u ptr
    @BenjaminLindley ty,我会试试的。顺便说一句,编译器生成的move构造函数应该在上面的代码段中给出正确的行为,对吗?由于命名构造函数的rhs无论如何都会消失(甚至可能通过RVO),我认为我是安全的。(我根本没有玩过移动构造函数…)感谢您检查这一点,但是如果您在
    #define NEXT_LINE_原因_CC_OF_IO
    中发表评论,构建将失败。很抱歉,我错过了那个。我调查了一下,编辑了我的答案。