复制语义和移动语义
复制语义(Copy Semantics)涉及创建对象的深层次副本,包含对其所有成员(包括指向的动态资源)的复制。移动语义(Move Semantics)则是C++11引入的一种优化,它允许“窃取”临时对象的资源,避免不必要的复制。
以下是一个简单的Vector
类的例子,该类具有动态分配的数组,用以展示复制语义和移动语义的区别:
1 |
|
拷贝构造函数(复制语义)
当你使用拷贝构造函数创建一个新的Vector
对象时,每个成员都会被复制到新对象中。对于动态分配的数组,会分配一块新的内存区域,并将原始数组的内容复制到这块新内存中。这保证了两个对象(原始对象和拷贝对象)之间的数据是完全独立的。
1 | Vector v1(10); // 创建一个Vector对象v1 |
在上述代码中,v2
是v1
的一个完整副本,v1
和v2
各自拥有各自的内存区域。
移动构造函数(移动语义)
当你使用移动构造函数创建一个新的Vector
对象时,原始对象的资源(在这里是动态分配的数组)会被“移动”到新对象中,而原始对象则被置于一个有效但“空”的状态(在这里是data_
指针设置为nullptr
,size_
设置为0)。这避免了不必要的复制,用于临时对象或即将被销毁的对象特别有效,因为它大幅度减少了性能开销。
1 | Vector v3(10); // 创建一个Vector对象v3 |
在上述代码中,v4
现在拥有原本属于v3
的内存,而v3
现在不再拥有任何资源,因此不会在析构时释放v4
正在使用的内存,从而避免了潜在的双重释放问题。
区别总结
- 复制语义:在使用拷贝构造函数时,会创建对象的独立副本,包括复制动态分配的资源。
- 移动语义:在使用移动构造函数时,会将资源的所有权从一个对象转移给另一个对象,通常这会留下一个处于安全但无资源的原始对象状态。