C++11 移动构造函数
C++11 move constructor
考虑到以下类,实现移动构造函数的正确方法是什么:
class C {
public:
C();
C(C&& c);
private:
std::string string;
}
当然,这个想法是避免复制string
或两次解除分配。
让我们假设基本示例只是为了清楚起见,我确实需要一个移动构造函数。
我试过了:
C::C(C&& c) {
//move ctor
string = std::move(c.string);
}
和
C::C(C&& c) : string(std::move(c.string)) {
//move ctor
}
两者都在 gcc 4.8 上编译良好且运行良好。选项A似乎是正确的行为,string
被复制而不是与选项B一起移动。
这是移动构造函数的正确实现吗?
由于std::string
本身有一个移动 ctor,因此隐式定义的 move-ctor 用于C
将负责正确的移动操作。您可能无法自己定义它。但是,如果您有任何其他数据成员,特别是:
12.8 复制和移动类对象
12 隐式声明的复制/移动构造函数是内联公共其类的成员。类 X 的默认复制/move 构造函数定义为已删除 (8.4.3(,如果 X 具有:
— 具有非平凡的对应构造函数和 X 是一个类似联合的类,
— 一类类型 M(或其数组(的非静态数据成员,不能被复制/移动,因为重载分辨率 (13.3(,应用于 M相应的构造函数,导致歧义或函数从默认构造函数中删除或无法访问,或者
— 一无法复制/移动的直接或虚拟基类 B,因为过载分辨率 (13.3(,适用于 B 的相应构造函数,导致歧义或删除函数或无法从默认构造函数访问,或
— 为了搬家构造函数、非静态数据成员或直接或虚拟基类使用没有移动构造函数且不平凡的类型可复制。
13 类 X 的复制/移动构造函数是微不足道的,如果它是既不是用户提供也不是删除的,如果
— 类 X 没有虚函数 (10.3( 和 没有虚拟基类 (10.1(,以及函数 (10.3( 和没有虚拟基类 (10.1(,以及
— 该选择用于复制/移动每个直接基类子对象的构造函数是琐碎,以及
— 对于 X 的每个非静态数据成员,该成员属于类类型(或其数组(,选择复制/移动该构造函数成员是微不足道的;否则,复制/移动构造函数是不平凡的。
您可能希望实现自己的移动控制。
如果需要 move-ctor,请首选初始值设定项列表语法。总是!否则,您最终可能会得到初始值设定项列表中未提及的每个对象的默认构造(这是仅对具有非默认 ctor 的成员对象强制使用的内容(。
您的两个变体都将移动字符串。应该首选第二个变体,因为它不会默认构造一个空字符串只是为了稍后移动分配它。
检查你的测试用例,然后检查编译器的bugzilla列表。如果要确保这两种情况都移动,则需要跟踪对string::operator=(string&&)
(第一种情况(和string::string(string&&)
(第2种情况(的调用。
两个构造函数都应该工作。所以两者都是正确的移动构造函数。第二个可能更有效率,因为第一个默认构造string
分配给它,而第二个将简单地移动构造它,因此应该更有效率。如果第二个效率较低,我会怀疑编译器错误(请记住,当前编译器的 C++11 支持仍然不完整(或有缺陷的测试方法(您究竟如何测试复制与移动,并且您确定在这两种情况下都调用移动构造函数而不是赋值操作?
当然,只要有可能,您就可以简单地让编译器通过 C(C&&) = default;
生成您的构造函数。
这里不需要实现移动构造函数,因为您不必手动管理内存。仅当您在类中手动使用动态数组时,Move 构造函数才有用。
您仍然可以显式地让编译器创建默认的移动构造函数,即使您没有请求它,它也应该已经完成:
C(C&& c) = default;
- 为什么不调用移动构造函数?(默认情况下只有构造器,没有别的)
- std::vector::p ush_back() 不会在 MSVC 上编译具有已删除移动构造函数的对象
- 仅包含可移动 std::map 的类的移动构造函数不起作用
- 为什么调用复制构造函数而不是移动构造函数?
- 基类中的默认析构函数禁用子类中的移动构造函数(如果有成员)
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 具有已删除移动和复制构造函数的类的就地构造
- 移动构造函数和右值引用
- 使用移动调用对等构造函数unique_ptr默认构造函数
- 为什么 std::memmove 中联合的默认非平凡移动构造函数C++?
- 具有专用化的模板类中的可靠条件复制和移动构造函数
- 构造函数采用std::string_view与std::string并移动
- C++:为什么不调用移动构造函数?
- 了解构造函数在移动、复制、赋值语义中的行为
- 没有移动的构造函数移动课程
- 引用绑定和复制构造函数/移动构造函数
- 构造函数移动
- C++ 向量实现 - 移动构造函数 - 移动与前进
- 我真的必须取消移动构造函数/移动结构中的所有成员还是只是指针
- 将类(没有默认构造函数)移动到另一个类的move构造函数中