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

相关文章
|
3月前
|
编译器 程序员 定位技术
C++ 20新特性之Concepts
在C++ 20之前,我们在编写泛型代码时,模板参数的约束往往通过复杂的SFINAE(Substitution Failure Is Not An Error)策略或繁琐的Traits类来实现。这不仅难以阅读,也非常容易出错,导致很多程序员在提及泛型编程时,总是心有余悸、脊背发凉。 在没有引入Concepts之前,我们只能依靠经验和技巧来解读编译器给出的错误信息,很容易陷入“类型迷路”。这就好比在没有GPS导航的年代,我们依靠复杂的地图和模糊的方向指示去一个陌生的地点,很容易迷路。而Concepts的引入,就像是给C++的模板系统安装了一个GPS导航仪
138 59
|
2月前
|
存储 安全 C++
【C++11】右值引用
C++11引入的右值引用(rvalue references)是现代C++的重要特性,允许更高效地处理临时对象,避免不必要的拷贝,提升性能。右值引用与移动语义(move semantics)和完美转发(perfect forwarding)紧密相关,通过移动构造函数和移动赋值运算符,实现了资源的直接转移,提高了大对象和动态资源管理的效率。同时,完美转发技术通过模板参数完美地转发函数参数,保持参数的原始类型,进一步优化了代码性能。
40 2
|
2月前
|
安全 编译器 C++
【C++11】新特性
`C++11`是2011年发布的`C++`重要版本,引入了约140个新特性和600个缺陷修复。其中,列表初始化(List Initialization)提供了一种更统一、更灵活和更安全的初始化方式,支持内置类型和满足特定条件的自定义类型。此外,`C++11`还引入了`auto`关键字用于自动类型推导,简化了复杂类型的声明,提高了代码的可读性和可维护性。`decltype`则用于根据表达式推导类型,增强了编译时类型检查的能力,特别适用于模板和泛型编程。
26 2
|
3月前
|
存储 编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(三)
【C++】面向对象编程的三大特性:深入解析多态机制
|
3月前
|
存储 编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(二)
【C++】面向对象编程的三大特性:深入解析多态机制
|
3月前
|
编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(一)
【C++】面向对象编程的三大特性:深入解析多态机制
|
3月前
|
C++
C++ 20新特性之结构化绑定
在C++ 20出现之前,当我们需要访问一个结构体或类的多个成员时,通常使用.或->操作符。对于复杂的数据结构,这种访问方式往往会显得冗长,也难以理解。C++ 20中引入的结构化绑定允许我们直接从一个聚合类型(比如:tuple、struct、class等)中提取出多个成员,并为它们分别命名。这一特性大大简化了对复杂数据结构的访问方式,使代码更加清晰、易读。
45 0
|
3月前
|
存储 编译器 C++
【C++】面向对象编程的三大特性:深入解析继承机制(三)
【C++】面向对象编程的三大特性:深入解析继承机制
|
3月前
|
编译器 C++
【C++】面向对象编程的三大特性:深入解析继承机制(二)
【C++】面向对象编程的三大特性:深入解析继承机制
|
3月前
|
安全 程序员 编译器
【C++】面向对象编程的三大特性:深入解析继承机制(一)
【C++】面向对象编程的三大特性:深入解析继承机制