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,它喜欢调用复制构造函数#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中不调用复制构造函数,而是调用移动构造函数,这是正常的:
在C++11中是可移动的std::ifstream
- 因此,
将具有有效的编译器生成的移动构造函数IO
- 由于您没有为
声明复制构造函数或移动构造函数,因此它也将有一个有效的编译器生成的move.constructorFoo
中的return语句将调用Foo::NamedConstructor
的move构造函数,而不是copy构造函数Foo
但是,您的测试代码(注释掉了
#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
中发表评论,构建将失败。很抱歉,我错过了那个。我调查了一下,编辑了我的答案。