une*_*lue 26 c++ move-semantics c++11
考虑以下类,实现移动构造函数的正确方法是什么:
class C {
public:
C();
C(C&& c);
private:
std::string string;
}
Run Code Online (Sandbox Code Playgroud)
当然,这个想法是避免复制string
或解除分配两次.
让我们假设基本的例子只是为了清晰,我确实需要一个移动构造函数.
我试过了:
C::C(C&& c) {
//move ctor
string = std::move(c.string);
}
Run Code Online (Sandbox Code Playgroud)
和
C::C(C&& c) : string(std::move(c.string)) {
//move ctor
}
Run Code Online (Sandbox Code Playgroud)
两者都在gcc 4.8上编译正常并运行良好.这似乎选项A是正确的行为,string
被复制,而不是使用选项B.移动
这是正确执行的举动构造的?
dir*_*tly 15
由于std::string
它本身有一个移动器,因此隐式定义的移动器C
将负责正确的移动操作.你可能不会自己定义它.但是,如果您有任何其他数据成员,具体如下:
12.8复制和移动类对象
12隐式声明的复制/移动构造函数是其类的内联公共成员.如果X具有以下内容,则将类X的默认复制/移动构造函数定义为已删除(8.4.3):
- 具有非平凡对应构造函数的变体成员,X是类似联合的类,
- 类型M(或其数组)的非静态数据成员,由于应用于M的相应构造函数的重载解析(13.3),无法复制/移动,导致模糊或被删除或无法访问的函数默认构造函数,或
- 无法复制/移动的直接或虚拟基类B,因为重载解析(13.3),应用于B的相应构造函数,导致模糊或从默认构造函数中删除或无法访问的函数,或者
- 对于移动构造函数,是一个非静态数据成员或直接或虚拟基类,其类型不具有移动构造函数,并且不易于复制.
13如果既不是用户提供也不是删除,那么X类的复制/移动构造函数是微不足道的
- 类X没有虚函数(10.3),没有虚基类(10.1),函数(10.3)和虚基类(10.1),以及
- 选择复制/移动每个直接基类子对象的构造函数是微不足道的,并且
- 对于类类型(或其数组)的X的每个非静态数据成员,选择复制/移动该成员的构造函数是微不足道的; 否则复制/移动构造函数是非平凡的.
你可能想要实现自己的移动.
如果您需要move-ctor,请选择初始化列表语法.总是!否则,您可能最终得到初始化列表中未提及的每个对象的默认构造(这是您仅对具有非默认ctors的成员对象强制执行的操作).
Joh*_*itb 11
你的变种都会移动字符串.第二个变体应该是首选的,因为它不会默认构造一个空字符串,只是为了之后移动赋值.
检查您的测试用例,然后检查编译器的bugzilla列表.如果要确保它们移动的两种情况,您需要跟踪对string::operator=(string&&)
第一种情况和 string::string(string&&)
第二种情况的调用.