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 转换的对象)时,意味着它即将被销毁,其资源可以被安全地“偷”过来。
 
                   
                   
                   
                   
                             
       
           
                 
                 
                 
                 
                 
                
               
                 
                 
                 
                 
                
               
                 
                 扫一扫
扫一扫
                     
              
             
                   588
					588
					
 被折叠的  条评论
		 为什么被折叠?
被折叠的  条评论
		 为什么被折叠?
		 
		  到【灌水乐园】发言
到【灌水乐园】发言                                
		 
		 
    
   
    
   
             
            


 
            