【c++】移动构造 移动赋值 转移 完美转发

【c++】移动构造 移动赋值 转移 完美转发

1. 移动构造(Move Constructor)

移动构造函数用于将资源从一个对象转移到另一个对象避免避免堆区资源反复创建和销毁

左值转换为右值调用其移动构造函数

特点:

  • 移动构造函数的参数是右值引用 (Type&&),用于接收一个临时对象的资源。
  • 资源的所有权从原对象转移到新对象,原对象通常会被置为空或进入“可析构但不可用”的状态。
  • 如果没有提供移动构造函数,编译器会回退到拷贝构造函数
  • const,因为移动操作会修改源对象。

示例:

#include <iostream>
#include <utility>  // std::move

class A {
public:
    int* data;

    A(int value) : data(new int(value)) { std::cout << "构造\n"; }

    // 移动构造函数
    A(A&& other) noexcept : data(other.data) {
        other.data = nullptr;  // 资源转移后,原对象置为空
        std::cout << "移动构造\n";
    }

    ~A() { delete data; }
};

int main() {
    A a(10);
    A b(std::move(a));  // 触发移动构造
    return 0;
}

优点

  • 避免深拷贝,减少资源分配,提高效率。

2. 移动赋值(Move Assignment)

移动赋值运算符用于将资源从一个已有对象转移到另一个已有对象

特点:
  • 释放当前对象的旧资源,并接管右值对象的资源。
  • 参数是右值引用 (Type&&)。
  • 必须释放原来的资源,防止内存泄漏!
  • 如果没有提供移动赋值,编译器会回退到拷贝赋值
示例:
class B {
public:
    int* data;

    B(int value) : data(new int(value)) { std::cout << "构造\n"; }

    // 移动赋值运算符
    B& operator=(B&& other) noexcept {
        if (this != &other) {  // 避免自我赋值
            delete data;       // 释放当前对象的旧资源
            data = other.data; // 资源转移
            other.data = nullptr;
        }
        std::cout << "移动赋值\n";
        return *this;
    }

    ~B() { delete data; }
};

int main() {
    B b1(10);
    B b2(20);
    b2 = std::move(b1);  // 触发移动赋值
    return 0;
}

b2 = std::move(b1); 将左值转化为右值->之后调用移动赋值

移动赋值 vs. 移动构造

移动构造移动赋值
适用场景用于创建新对象用于已有对象赋值
是否释放旧资源不需要需要先释放已有资源
参数类型Type&&(右值引用)Type&&(右值引用)

3. 资源转移

资源转移指的是对象 A 的资源被转交给对象 B,而 A 变为空或不再使用

A a(10);
A b(std::move(a));  // a 的资源被转移给 b,a.data 变为 nullptr

关键点

  • 资源从原对象转移给新对象。

4. 完美转发

完美转发 (std::forward) 确保参数传递时保持左值/右值属性 不发生改变

示例:

#include <iostream>

void func(int& x) { std::cout << "左值引用\n"; }
void func(int&& x) { std::cout << "右值引用\n"; }

template <typename T>
void wrapper(T&& arg) {
    func(std::forward<T>(arg));  // 保持传入参数的左值/右值属性
}

int main() {
    int x = 10;
    wrapper(x);         // 传递左值,调用 `void func(int&)`
    wrapper(20);        // 传递右值,调用 `void func(int&&)`
}

完美转发 vs. std::move

std::movestd::forward
作用强制转换为右值保留原始左值/右值属性
适用场景资源转移模板参数传递
是否影响原对象

总结

概念作用参数类型
移动构造资源转移,新建对象Type&&
移动赋值资源转移,已有对象Type&&
资源转移资源从 A 转移到 B-
完美转发传递参数,保持左值/右值T&& + std::forward<T>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值