c++的右值引用具体用法

在c++11中,支持右值引用,右值引用的用处之一是移动语义,对象的资源所有权发生转移,在c++11之前,移动语义的缺失是c++饱受诟病的问题之一.

什么是左值?什么是右值?

凡有名者,皆为左值.左值对应变量的存储位置,右值对应变量的值本身,右值可以被赋值给左值,或者绑定到引用.

右值引用的优点?

类的右值是一个临时对象,如果没有被绑定到引用,在表达式结束时候,就会废弃,在右值被废弃之前,移走资源进行废物利用.

被移走资源的右值在废弃时已经成为空壳,析构的开销降低.

为临时变量续命,也就是为右值续命,右值在表达式结束后就消亡了,如果想继续使用右值,就会使用昂贵的拷贝构造函数

如果能够直接使用临时对象已经申请的资源,既能节省资源,又能节省资源申请和释放的时间

看一个具体的例子:

#include <iostream>
#include <utility>
#include <vector>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

class TestString
{
        private:
                char *data_;
                size_t len_;
                void _init_data(const char *p)
                {
                        data_ = new char[len_ + 1];
                        memcpy(data_, p, len_);
                        data_[len_] = '\0';
                }
        public:
                TestString()
                {
                        data_ = NULL;
                        len_ = 0;
                }

                TestString(const char *p)
                {
                        len_ = strlen(p);
                        _init_data(p);
                }

                TestString(const TestString &str)
                {
                        len_ = str.len_;
                        _init_data(str.data_);
                        std::cout << "Copy Structor is called! source:" << str.data_ << std::endl;
                }

                TestString& operator=(const TestString &str)
                {
                        if(this != &str)
                        {
                                len_ = str.len_;
                                _init_data(str.data_);
                        }
                        std::cout << "Copy Assignment is called! source:" << str.data_ << std::endl;
                        return *this;
                }

                //TestString(TestString &&str)
                //{
                //        std::cout << "Move Constructor is called! source:" << str.data_ << std::endl;
                //        len_ = str.len_;
                //        data_ = str.data_;
                //        str.len_ = 0;
                //        str.data_ = NULL;
                //}

                //TestString& operator=(TestString &&str)
                //{
                //        std::cout << "Move Assignment is called! source:" << str.data_ << std::endl;
                //        if(this != &str)
                //        {
                //                len_ = str.len_;
                //                data_ = str.data_;
                //                str.len_ = 0;
                //                str.data_ = NULL;
                //        }
                //        return *this;
                //}
                virtual ~TestString()
                {
                        if(data_)
                        {
                                delete []data_;
                                data_ = NULL;
                        }
                }
};

int main(int argc, char *argv[])
{

        TestString a;
        a = TestString("Hello ");
        std::vector<TestString> vec;
        vec.push_back(TestString(" Wrold"));
        return 0;
}

说明两点:

(1)左值引用符号&,右值引用符号&&,右值引用符号只有在c++11中才被支持;

(2)程序中的注释部分,包含右值引用拷贝构造函数和右值引用赋值构造函数,取消注释前后程序的运行结果不一致,可以体会一下右值引用的含义,以及移动语义的优点:

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

seasermy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值