我一直在阅读C ++ 11的新移动语义,而且我不清楚的是,如果使用自定义构造函数会阻止编译器自动向您的类添加移动语义。我不明白5的规则是否也包括如下的简单类。
我有以下课程:
class CodeFile
{
private:
std::vector<Function> functions;
//std::vector<std::wstring, unsigned long> variables;
std::vector<std::wstring> lines;
std::vector<unsigned char> constants;
public:
std::wstring directory;
std::wstring fileName;
void setFilePath(std::wstring filePath);
bool addFunction(Function function);
void Run();
void Finalize();
CodeFile(std::wstring filePath);
};
最后一行是构造函数。定义此构造函数是否会阻止编译器通过添加移动构造函数来优化类?
我应该将该课程声明如下吗?
class CodeFile
{
private:
std::vector<Function> functions;
//std::vector<std::wstring, unsigned long> variables;
std::vector<std::wstring> lines;
std::vector<unsigned char> constants;
public:
std::wstring directory;
std::wstring fileName;
void setFilePath(std::wstring filePath);
bool addFunction(Function function);
void Run();
void Finalize();
static CodeFile fromFile(std::wstring filePath);
};
答案 0 :(得分:3)
您无需在此处执行任何操作。 C ++将为您编写移动构造函数。
但是,无论何时您担心这一点,只需添加
即可CodeFile(CodeFile &&)=default;
CodeFile(CodeFile const&)=default;
CodeFile& operator=(CodeFile &&)=default;
CodeFile& operator=(CodeFile const&)=default;
可能
CodeFile()=default;
这是一个令人烦恼的样板,但它也是无害的,并表示你希望这个类是可复制的和可移动的(或者你是疯狂的通用代码,并希望它的复制/可移动性依赖于它的父母和内容)。
请注意,除非是真正的转换,否则你不应该有一个非显式的单一参数构造。请考虑explicit
上的CodeFile(std::wstring)
。
但是,任何禁用CodeFile(CodeFile&&)
自动书写功能的内容也会禁用CodeFile(CodeFile const&)
的自动书写功能。因此,如果您发现无法再复制它,您也可以不再移动它(除非您手动编写CodeFile(CodeFile const&)
,这当然会在不禁用自身的情况下禁用CodeFile(CodeFile&&)
。)。
为了诊断这样的事情,我经常写noisy
:
struct noisy {
noisy(){std::cout << "ctor()\n";}
noisy(noisy&&){std::cout << "ctor(&&)\n";}
noisy(noisy const&){std::cout << "ctor(c&)\n";}
void operator=(noisy&&){std::cout << "asgn(&&)\n";}
void operator=(noisy const&){std::cout << "asgn(c&)\n";}
~noisy() {std::cout << "~\n"; }
};
除了发出噪音外什么也没做。
然后我们写一个玩具类型:
struct Foo {
Foo (int) {}
noisy _;
};
我们关心的属性。
进行一些测试:
Foo f(7);
f = Foo(3);
Foo f2=std::move(f);
表明移动构造函数很好。我们编写Foo
。
Foo(int)
中删除了默认构造函数
答案 1 :(得分:1)
我应该将该课程声明如下吗? ...
没有。只需声明您需要自动生成的构造函数,如下所示
CodeFile(CodeFile&&) = default;