类和五个特殊的函数紧密联系在一起,它们分别是析构函数destructor,拷贝构造函数(copy construct,移动构造函数(move constructor),拷贝赋值函数(copy assignment operator)和移动赋值函数(copy assignment operator)。当类中含有指针作为数据成员时,默认的拷贝以及析构函数会出现问题,必须自己定义。释放自己定义的动态内存,并且在拷贝时实施深拷贝。
#include<iostream>
using namespace std;
class IntCell
{
public:
explicit IntCell(int initialValue = 0)
{
storedValue = new int{ initialValue };
}
~IntCell()
{
delete storedValue;
}
IntCell(const IntCell& rhs)
{
storedValue = new int{ *rhs.storedValue };
}
IntCell(IntCell&& rhs) :storedValue{ rhs.storedValue }
{
rhs.storedValue = nullptr;
}
IntCell& operator=(const IntCell& rhs)
{
IntCell copy = rhs;
swap(*this, copy);
return *this;
}
IntCell& operator=(IntCell&& rhs)
{
swap(storedValue, rhs.storedValue);
return *this;
}
private:
int *storedValue;
};
int main()
{
IntCell a{ 2 };
IntCell b = a;
IntCell c;
b = move(c);
return 0;
}
注意:
swap是通过三次移动实现的
template<class _Ty,
class> inline
void swap(_Ty& _Left, _Ty& _Right)
_NOEXCEPT_COND(is_nothrow_move_constructible_v<_Ty>
&& is_nothrow_move_assignable_v<_Ty>)
{ // exchange values stored at _Left and _Right
_Ty _Tmp = _STD move(_Left);
_Left = _STD move(_Right);
_Right = _STD move(_Tmp);
}
因此移动赋值中交换的是成员,若改为对象则会出现无休止递归的情况,因为在swap中右出现了移动赋值。拷贝构造函数传递的是常量引用,若不是引用也会出现无休止递归的情形。