C++左值引用、右值引用、移动语义、完美转发、深浅拷贝

一、左值和右值定义(能否取地址
1.左值:可以取地址的对象
2.右值:不可以取地址、临时要销毁的对象

二、左值引用
1.定义:对左值的引用

int& ra = a;

2.作用:传递参数和返回值时减少不必要的拷贝

三、右值引用
1.定义:对右值的引用

// 以下是对几种右值的右值引用
int&& rr1 = 10;
double&& rr2 = x + y;
double&& rr3 = fmin(x, y);

2.作用
(1)移动语义:减少两个对象交互时不必要的拷贝,节省运算存储资源,提高效率
(2)完美转发:更加简洁准确地定义泛型函数

四、移动语义中的移动构造函数
定义:移动构造函数是一个接受右值引用参数的构造函数,它用于将资源从一个对象转移到另一个对象。移动构造函数的实现通常会“窃取”源对象的资源,并将源对象的资源指针(或其他表示资源的成员)置为空,从而确保源对象不再拥有这些资源。

class MyObject {
public:
    // 移动构造函数
    MyObject(MyObject&& other) noexcept {
        // 窃取资源
        resource_ = other.resource_;
        other.resource_ = nullptr; // 将源对象的资源指针置为空
    }

    // 其他成员和方法...
private:
    Resource* resource_; // 假设Resource是一种动态分配的资源类型
};

五、完美转发
泛型函数是一种能够在不指定具体类型的情况下工作的函数,它们通常使用模板来实现。泛型函数允许在编写代码时延迟类型的指定,使得函数可以处理各种不同类型的数据。
右值引用可以更简洁明确地定义泛型函数,因为它们提供了对右值的特定支持,使得函数能够在不必要的拷贝的情况下处理临时对象。在C++11之前,泛型函数可能会导致对传递的参数进行不必要的深拷贝,特别是对于临时对象(右值)的处理。而右值引用使得我们可以针对右值和左值分别进行优化,从而避免了不必要的资源拷贝。
举例来说,考虑一个简单的模板函数,该函数接受一个参数并返回其两倍值:

template<typename T>
T doubleValue(T value) {
    return value * 2;
}

在这个函数中,无论传递的是左值还是右值,参数都会被复制一次,这可能会导致性能损失,特别是对于大型对象或临时对象而言。
通过使用右值引用,我们可以更明确地指定函数接受右值参数,并对其进行优化:

template<typename T>
T doubleValue(T&& value) {
    return value * 2;
}

现在,这个函数可以接受左值和右值,并根据参数类型进行适当的优化。如果传递的是右值,那么不会发生额外的拷贝,因为右值引用允许我们在需要时直接访问临时对象。这使得函数更加灵活和高效,同时也更清晰地表达了函数的意图,即该函数可以接受任意类型的参数,并返回其两倍值,而不会产生不必要的开销。

六、浅拷贝和深拷贝(有无资源的重新分配)
1.浅拷贝只复制指针或引用,将源对象的值拷贝到目标对象中去,本质上来说源对象和目标对象共用一份实体,只是所引用的变量名不同,地址其实还是相同的,因此复制后的对象共享相同的资源。
2.拷贝的时候先开辟出和源对象大小一样的空间,然后将源对象里的内容拷贝到目标对象中去,这样两个指针就指向了不同的内存位置,并且里面的内容是一样的。

class ShallowCopy {
public:
    int* data;

    // 构造函数
    ShallowCopy(int val) {
        data = new int(val);
    }

    // 拷贝构造函数(浅拷贝)
    ShallowCopy(const ShallowCopy& other) {
        data = other.data; // 只复制指针,而不是分配新的内存
    }  

    // 拷贝构造函数(深拷贝)
    DeepCopy(const DeepCopy& other) {
        data = new int(*other.data); // 分配新的内存并复制数据
    }

    // 析构函数
    ~ShallowCopy() {
        delete data;
    }
};
  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值