C++为什么要引入右值概念(一)?

一,综述

C++最早没有右值的概念,自从C++11以后引入右值概念。那么什么是右值呢?举例如下:

int a = 10;

a就是传统的变量,称为左值。10为常量,称为右值。左值是可以取得其地址的,右值是不能取得其地址的。我们可以用&a来取得变量a的地址,但10不能使用&符号,因此a为左值,10为右值。函数的返回值也是一个右值。

如函数:

int add(int a, int b)
{
    int sum = a + b;
    return sum;
}

此函数返回一个sum,我们无法取得sum的地址,因此函数的返回值是一个右值。

那么为什么C++ 11要引入右值的概念呢?我们先举一个例子。

二,没有右值引用的情况下的例子

先上代码:


#include <iostream>
using namespace std;

class MyBlob
{
private:
    char* m_p;
    int m_size;
public:
    MyBlob(): m_p(nullptr), m_size(0) {}
    MyBlob(int size)
    {
        m_p = new char[size];
        m_size = size;
        cout << "Construct " << m_size << " bytes" << endl;
    }
    ~MyBlob()
    {
        if(!m_p)
        {
            delete[] m_p;
            m_p = nullptr;
        }
        m_size = 0;
    }
    MyBlob(const MyBlob& b)
    {
        cout << "Copy Construct " << endl;
        m_size = b.m_size;
        m_p = new char[m_size];
        memcpy(m_p, b.m_p, m_size);
    }
    MyBlob& operator=(const MyBlob& b)  //拷贝赋值
    {
        cout << "Copy assignment......" << endl;
        if (!m_p)
        {
            delete[] m_p;
        }
        m_size = b.m_size;
        m_p = new char[m_size];
        memcpy(m_p, b.m_p, m_size);
        return *this;
    }
    MyBlob& operator=(MyBlob& b)  //移动赋值
    {
        cout << "Move assignment ......" << endl;
        if (!m_p)
        {
            delete[] m_p;
        }       
        m_p = b.m_p;
        m_size = b.m_size;
        b.m_p = nullptr;
        b.m_size = 0;     
        return *this;
    }
    void print()
    {
        cout << "this = " << static_cast<void*>(this) <<  ", addr " << static_cast<void*>(m_p) << ",size = " << m_size << endl;
    }
};

int main()
{
    MyBlob a(10);
    MyBlob b1(100);
    
    b1 = a;  //调用移动赋值函数

    MyBlob b(100);
    const MyBlob& c = b;
    MyBlob b2(1000);
    b2 = c;  //调用拷贝赋值函数
}

MyBlob类中重载了两次运算符“=”,第一个为拷贝赋值函数,第二个为移动赋值函数。移动赋值函数不重新分配内存,直接使用b的内存,同时把b的内存指针设置为null,这样就省去了拷贝过程,因此可以提高运行速度。

我们如何能分别调用拷贝赋值函数和移动赋值函数呢?上述代码中:b1 = c 会调用移动赋值函数,如果需要使用拷贝赋值函数,则需要使用如下代码:

    MyBlob b(100);
    const MyBlob& c = b;
    MyBlob b2(1000);
    b2 = c;  //调用拷贝赋值函数

需要重新声明一个b的const引用,这样b2=c就会调用拷贝构造函数。这样是不是比较麻烦?这时该右值出场了。

未完待续

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值