C20 移动构造与移动赋值

3.1移动构造函数

移动构造函数用于从一个右值对象构造一个新对象。它直接接管源对象的资源,避免深拷贝。

class MyString {

private:

char* m_data;

size_t m_size;

public:

// 移动构造函数

MyString(MyString&& other) noexcept // 标记为noexcept非常重要

: m_data(other.m_data) // 1. 直接“窃取”指针

, m_size(other.m_size)

{

// 2. 将源对象置于可安全析构的状态

other.m_data = nullptr;

other.m_size = 0;

std::cout << "Move Constructor called" << std::endl;

}

// 注意:必须实现析构函数来释放资源

~MyString() {

delete[] m_data;

}

// ... 其他成员函数,如普通构造函数、析构函数等

};

// 使用场景

MyString CreateString() {

MyString temp("Hello");

return temp; // 编译器可能会进行RVO,否则会尝试使用移动构造

}

int main() {

MyString s1 = CreateString(); // 可能调用移动构造

MyString s2 = std::move(s1); // 明确使用移动构造,s1不再拥有数据

}

3.2移动赋值运算符

移动赋值运算符用于将一个右值对象的资源移动到一个已经存在的对象中。

class MyString {

// ... 其他成员同上

public:

// 移动赋值运算符

MyString& operator=(MyString&& other) noexcept {

// 1. 检查自我赋值

if (this != &other) {

delete[] m_data; // 2. 释放自身原有资源

// 3. 窃取资源

m_data = other.m_data;

m_size = other.m_size;

// 4. 置空源对象

other.m_data = nullptr;

other.m_size = 0;

}

std::cout << "Move Assignment Operator called" << std::endl;

return *this; // 5. 返回当前对象的引用

}

};

// 使用场景

int main() {

MyString s1("Hello");

MyString s2("World");

s2 = std::move(s1); // 调用移动赋值运算符,s1的资源被转移给s2

}

3.3总结与对比

下面这个表格概括了它们的核心特征:

特性

移动构造函数

移动赋值运算符

声明语法

 ClassName  (ClassName&& other) 

 ClassName  & operator=(ClassName&& other) 

参数

同类类型的右值引用 ( ClassName  && )

同类类型的右值引用 ( ClassName  && )

核心操作

“窃取”源对象  other  的资源(如指针)

先释放自身原有资源,再“窃取”  other  的资源

关键步骤

将源对象  other  的指针成员置为  nullptr  等安全状态

将源对象  other  的指针成员置为  nullptr  等安全状态

返回值

返回当前对象的左值引用 ( ClassName  & ),以支持链式赋值

异常安全

应标记为  noexcept ,便于标准库优化

应标记为  noexcept 

编译器生成

满足特定条件时编译器可自动生成(通常类无自定义拷贝操作等)

满足特定条件时编译器可自动生成

移动语义的核心思想是资源所有权的转移。当一个对象是右值(如临时对象、被  std::move  转换的对象)时,意味着它即将被销毁,其资源可以被安全地“偷”过来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值