Copy And Move Semantics
搜索了点关于拷贝语义和移动语义的知识,有点感悟,在此记录一下。
拷贝构造函数和拷贝赋值运算符的行为
- 默认拷贝构造函数/拷贝赋值运算符
- Class type:调用该类成员的拷贝构造函数/拷贝赋值运算符
- C array:挨个元素拷贝/赋值
- Scalar type(int, float等等):调用内置赋值运算符
- 显示定义了拷贝构造函数/拷贝赋值运算符
- 所有行为均由用户定义。只有显示使用初始化列表拷贝构造/赋值类成员,才会调用类成员的拷贝构造/赋值
移动构造函数/移动赋值运算符的行为
- 默认移动构造函数/移动赋值运算符
- Class type:调用该类成员的移动构造函数/移动赋值运算符
- C array:挨个元素拷贝/赋值
- Scalar type(int, float等等):调用内置赋值函数
- 显示定义了移动构造函数/移动赋值运算符
- 所有行为均由用户定义。只有显示使用初始化列表移动构造/移动赋值类成员,才会调用类成员的移动构造函数/移动赋值运算符
心得
-
只有class type才有拷贝构造函数、拷贝赋值运算符、移动构造函数、移动赋值运算符。C array和Scalar type不管是在拷贝语义还是移动语义里其实都只是在做赋值/拷贝,我们可以把他们当做一块内存来看待,不用附加过多语义,而对于一块内存,就只有赋值/拷贝的概念。声明一个C array或者 Scalar type时必须显示赋值/拷贝,否则内存上的值是无法预测的。
-
将一个类和它的的class type 成员递归展开,如果没有指针/资源,则移动语义没有意义,移动构造函数等价于拷贝构造函数,移动赋值函数等于移动赋值函数。
-
栈中数据的内存大小和位置是固定的,位置是相对于栈起始位置的偏移,因此 std::array<int, 5> a = std::move(b)没有意义,并不会把a变量改成b的地址和大小。(我之前竟然有这个想法…真是太蠢了)