C++11新特性之右值引用

1.介绍

        右值引用是C++11引入的一种重要特性,它主要用于实现移动语义和完美转发,从而提高程序的性能与效率。

2.左值与右值

        在C++中,表达式可以分为左值与右值。左值通常是可以取地址的表达式,例如变量名。右值则是不能取地址的临时对象、字面量等。

        判断一个表达式是左值还是右值常用的方法有两种。

        (1)位于赋值号(=)左侧的表达式是左值,反之,只能位于右侧的表达式就是右值。

        例如:

                int  a = 1;

                1 = a;//错误,1不能为左值

        (2)有名称的、可以获取存储地址的表达式即为左值,反之则为右值。

        例如,上边的a可以通过&a获取地址,所以其为左值;反之字面量1既没有名称、也无法获取地址,因此为右值。

        注意,上边两种方法只适用于大部分场景。本节主要介绍右值引用,这里不在赘述,感兴趣的读者可自行了解。

3.右值引用的用法

        之前的C++标准中有引用,但只能操作左值,无法对右值添加引用。例如:

int num = 10;
int &b = num; //正确
int &c = 10; //错误

        如上所示,编译器允许我们对num左值建立引用,但不能对10这个右值建立引用。因此,这种引用又称为左值引用。

注意,虽然 C++98/03 标准不支持为右值建立非常量左值引用,但允许使用常量左值引用操作右值。

        因此,C++11引入了另一种引用方式,称为右值引用,用“&&”表示。 

        右值引用的声明语法如下:

                类型 && 引用名 = 右值表达式;

        例如:

int num = 10;
//int && a = num;  //右值引用不能初始化为左值
int && a = 10;

4.右值引用的用途

        (1)移动语义。

        它允许我们将一个对象的资源从一个对象转移到另一个对象,而不是进行深拷贝。通过移动语义,可以避免不必要的内存分配与数据赋值,从而提高程序的性能。

        通过移动构造函数实现,举个例子:

class demo{
public:
    
    //普通构造函数

    //移动构造函数
    demo(demo &&d):num(d.num){
        d.num = NULL;
        cout<<"move construct!"<<endl;
    }
private:
    int *num;
};

        当类中同时包含拷贝构造函数和移动构造函数时,如果使用临时对象初始化当前类的对象,编译器会优先调用移动构造函数来完成此操作。只有当类中没有合适的移动构造函数时,编译器才会退而求其次,调用拷贝构造函数。

        除此之外,C++还提供了一个move()函数,将左值强制转换为右值。实现左值初始化同类对象也通过移动构造函数实现。

        (2) 完美转发

        完美转发是指函数模版可以将自己的参数“完美”地转发给内部调用的其他函数。“完美”指步进能准确地转发参数值,还能保证被转发参数的左。右值属性不变。例如:

//实现完美转发的函数模板
template <typename T>
void function(T&& t) {
    otherdef(forward<T>(t));
}

        上边即为实现完美转发的函数模版,其中forward()为C++11标准的开发者引入的一个模版函数。(其详细实现过程比较复杂,所以直接上结论,感兴趣的可以自行研究)。

5.总结

        右值引用的核心目的就是为了实现移动语义(解决深拷贝带来的性能问题)与完美转发(参数传递过程中保持其原始左值或右值属性)。

        注意事项:

        (1)生命周期:右值引用绑定的临时对象生命周期会被延长,知到右值引用的生命周期结束。但需要注意的是,一旦临时对象的资源被移动,就不能使用该临时对象。

        (2)noexcept 声明:移动构造函数通常应该声明为 noexcept,这样可以让标准库容器在进行元素移动时更加高效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值