C++ 11移动构造函数

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&&)第二种情况的调用.