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

简介: 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

相关文章
|
1月前
|
编译器 程序员 定位技术
C++ 20新特性之Concepts
在C++ 20之前,我们在编写泛型代码时,模板参数的约束往往通过复杂的SFINAE(Substitution Failure Is Not An Error)策略或繁琐的Traits类来实现。这不仅难以阅读,也非常容易出错,导致很多程序员在提及泛型编程时,总是心有余悸、脊背发凉。 在没有引入Concepts之前,我们只能依靠经验和技巧来解读编译器给出的错误信息,很容易陷入“类型迷路”。这就好比在没有GPS导航的年代,我们依靠复杂的地图和模糊的方向指示去一个陌生的地点,很容易迷路。而Concepts的引入,就像是给C++的模板系统安装了一个GPS导航仪
105 59
|
1月前
|
存储 编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(三)
【C++】面向对象编程的三大特性:深入解析多态机制
|
1月前
|
存储 编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(二)
【C++】面向对象编程的三大特性:深入解析多态机制
|
1月前
|
编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(一)
【C++】面向对象编程的三大特性:深入解析多态机制
|
1月前
|
存储 安全 编译器
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值(一)
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值
|
30天前
|
C++
C++ 20新特性之结构化绑定
在C++ 20出现之前,当我们需要访问一个结构体或类的多个成员时,通常使用.或->操作符。对于复杂的数据结构,这种访问方式往往会显得冗长,也难以理解。C++ 20中引入的结构化绑定允许我们直接从一个聚合类型(比如:tuple、struct、class等)中提取出多个成员,并为它们分别命名。这一特性大大简化了对复杂数据结构的访问方式,使代码更加清晰、易读。
32 0
|
1月前
|
存储 编译器 C++
【C++】面向对象编程的三大特性:深入解析继承机制(三)
【C++】面向对象编程的三大特性:深入解析继承机制
|
1月前
|
编译器 C++
【C++】面向对象编程的三大特性:深入解析继承机制(二)
【C++】面向对象编程的三大特性:深入解析继承机制
|
1月前
|
安全 程序员 编译器
【C++】面向对象编程的三大特性:深入解析继承机制(一)
【C++】面向对象编程的三大特性:深入解析继承机制
|
1月前
|
存储 编译器 程序员
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值(二)
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值