关于c++的 右值 右值引用 move

简介

第一次接触c++move操作就懵逼了,一直想探个究竟,但是右值以及右值引用思考了好长时间,就是不得要领,今天终于有所收获,写下第一篇博客,一方面为了帮助一些刚入门的朋友,另一方面也是帮助自己今后复习。

右值 左值 右值引用 左值引用 含义

左值是一个持久的量,右值是一个短暂的量。那怎么算持久怎么算短暂呢?取决于我的代码里有没有一个变量来保存他。举个例子:
int i = 5;
string s1(“ppap”);
都可以完成取地址的操作的操作 &i,&si;
那么定义一个左值引用,就是给这些地址起一个其他的名字罢了,地址是不会发生变化的,也就是说左值引用的本质其实还是指针:
int &k = i;
string & s2 = s1;
右值就不一样了,右值是一个即将消亡的值,那么怎么算即将消亡?就是没有人记得他了:
string (“ppap”);
这样一个语句的的确确在这个函数栈中构造了这么一个空间,只不过可惜的是他是没有名字的!如果我在这个语句段中执行赋值或者拷贝,那么他起到了临时变量的作用:
string s1 = string(“ppap”);
但是一旦离开这一段语句,我就再也找不到这段空间的地址了,也就是一定意义上的消亡,但是这个消亡指的是没有人记得他了,它自身真正的消失是发生在函数栈清除;
那么理解了右值就可以说明什么是右值引用了。右值引用的含义就是,我想记下这个临时的,快要消亡的,马上就没得人记得他的名字(地址)。
那么换句话说:
const int & i = 1;
int && i = 1;
其实在某些意义上是等价的(不是完全等价)

右值引用的意义以及move

关于右值引用的意义,我的理解是:告诉编译器,这个变量我不要了,在执行赋值、拷贝构造等操作的时候,调用我提供的移动构造函数!
而move的底层其实就是一个静态强制转换,无论你是什么类型,一律变成右值引用类型,去强制匹配提供的右值引用形参的函数(用于实现接管资源)。

综上所述,右值引用在我看来有两种作用:
1:获取一个匿名临时变量的地址。
2:通过move强制转换告诉编译器,这个变量我不需要了,请帮我调用形参为右值引用的函数,来接管这份资源。
下面给一个例子在这里插入代码片

class str {
public:
	friend ostream& operator <<(ostream& out, const str& p);
    str() :data(nullptr), len(0) {}
	    //构造函数
    str(const char* p) {
        len = strlen(p);
        data = new char[len + 1];
        strcpy(data, p);
        cout << "执行了char * 的构造函数" << endl;
    }
   str(const str& p) {
        len = p.len;
        data = new char[len+1];
        strcpy(data, p.data);
        cout << "执行了 拷贝构造函数" << endl;
    } 
    str& operator = (const str & p){
        if (this == &p) return *this;
        delete []data;
        len = p.len;
        data = new char[len + 1];
        strcpy(data, p.data);
        cout << "执行了拷贝赋值" << endl;
        return *this;
    }
     str(str&& p) {
        if (this != &p) {
            len = p.len;
            data = p.data;
            p.data = nullptr;
            p.len = 0;
            cout << "执行了移动构造" << endl;
        }
         ~str() {
        delete[]data;
        cout << "执行了析构" << endl;
    }
private:
    char * data;
    int len;
};
ostream& operator<<(ostream& out, const str& p) {
    out << p.data;
    return out;
}
int main()
{
    str s1("ppppp");
    str s3 = s1;
    str s2(std::move(s1));
}

结果为:在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值