C++新特性 右值引用&&

本篇文章来讲一下C++新特性右值引用

1.区分左值和右值

左值:在内存中具有地址的 可以修改的值

右值:在内存中没有地址的 不可修改的值

注意 不能通过等式左边就是左值 等式右边就是右值 是不对的

比如:

int a=10;

int b=a;

a是左值  b也是值

右值引用语法:

int&&a=value;

注意 左值引用不能混用 左值引用不能引用右值 右值引用不能引用左值

右值引用的意义在于延长右值的生命周期 优化C++性能代码

右值引用的意义:

1.可以对返回的临时对象直接引用  不需要再将临时区的对象(将亡值)拷贝到本身的值当中

2.C++拷贝构造函数 移动拷贝构造函数

3.核心要点是对内存的拷贝省略 避免资源的浪费

那我们接下来对移动拷贝构造函数来进行讲解:

移动拷贝构造函数(Move Copy Constructor)是C++11引入的一种特殊构造函数,用于在对象之间执行有效的资源转移而不需要进行深拷贝。

移动拷贝构造函数通过右值引用参数来接收要被移动的对象,并将其资源所有权转移到新创建的对象上。通常,它会接受一个可变右值引用(T&&),其中T是类类型。

移动拷贝构造函数代码示例:

#include <iostream>

class MyClass {
private:
    int* data;

public:
    MyClass() : data(nullptr) {}
    
    // 移动拷贝构造函数
    MyClass(MyClass&& other) noexcept : data(other.data) {
        other.data = nullptr;
        std::cout << "Move constructor called" << std::endl;
    }

    void setData(int value) {
        data = new int(value);
    }

    ~MyClass() {
        if (data != nullptr)
            delete data;
    }
};

int main() {
    MyClass obj1;
    obj1.setData(42);

    // 使用移动拷贝构造函数创建新对象
    MyClass obj2(std::move(obj1));

    return 0;
}

在上述示例中,MyClass定义了一个移动拷贝构造函数。该构造函数将传入的对象(右值引用)的资源所有权转移到新创建的对象中,并设置源对象的指针为空。在主函数中,我们通过调用std::move来将obj1转换为右值,并使用移动拷贝构造函数创建了obj2

移动语义可以在处理大型资源时提供性能优势,避免不必要的数据复制和内存分配。需要注意,在移动后源对象的状态可能会变为未定义,所以在移动后最好不要再对其进行操作。同时,需要确保在移动构造函数中正确管理资源(如释放或重新分配内存)以避免资源泄漏和悬空指针问题。

既然说到移动拷贝构造函数了 那也同时说一下移动赋值运算符:

在采用右值引用的时候编译器没有为我们准备=   所以我们药自定义运算符

代码示例:

#include <iostream>

class MyClass {
private:
    int* data;

public:
    MyClass() : data(nullptr) {}

    // 移动复制运算符
    MyClass& operator=(MyClass&& other) noexcept {
        if (this == &other)
            return *this;

        delete data;
        data = other.data;
        other.data = nullptr;
        
        std::cout << "Move assignment operator called" << std::endl;

        return *this;
    }

    void setData(int value) {
        data = new int(value);
    }

    ~MyClass() {
        if (data != nullptr)
            delete data;
    }
};

int main() {
    MyClass obj1;
    obj1.setData(42);

    MyClass obj2;
    obj2.setData(100);

    // 使用移动复制运算符将obj1的资源转移到obj2
    obj2 = std::move(obj1);

   return 0; 
}

采用static_cast<T>可以将左值转换成为右值

int i=0;

int&&j=i;//编译失败

int &&j=static_cast<int&&>(i);//编译成功

万能引用:(原理是根据函数模板T来支持万能引用)根据类型自动推导值 但是不能同时两个以上的类型

格式规范:

template  <class T>

void bar(T&&t)(这里是右值引用的表达方式 假设函数名是bar)

void bar(T&&t)(这里是左值引用的表达方式 假设函数名是bar)

万能引用核心算法 :引用折叠规则

根据这个表来判断最终类型

总结:右值引用主要是为了C++中内存的调用 省略内存的调用 节省空间和资源 移动拷贝运算符和右值引用的原理相似 注意operator的使用

好了 本篇文章就写到这里了 在这里给大家推荐一个课程:
https://xxetb.xetslk.com/s/2PjJ3T

  • 25
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值