当前位置: 首页> 健康> 养生 > 常用的网络营销的方法_类似互推商盟的推广平台_各大网站收录查询_如何做推广和引流

常用的网络营销的方法_类似互推商盟的推广平台_各大网站收录查询_如何做推广和引流

时间:2025/8/28 10:40:05来源:https://blog.csdn.net/hujiahangdewa/article/details/147198440 浏览次数:0次
常用的网络营销的方法_类似互推商盟的推广平台_各大网站收录查询_如何做推广和引流

天天开心!!!

文章目录

  • 一、什么是左值和右值?
    • 1. 左值(Lvalue)
    • 2. 右值(Rvalue)
    • 3. 右值的两种分类
    • 4. 左值引用(Lvaue Reference)
    • 5. 右值引用(Rvalue Reference)
  • 二、std::move()
    • 1. std::move()的作用
    • 2. std::move()的底层原理


一、什么是左值和右值?

1. 左值(Lvalue)

  • 具有地址
  • 可以出现在赋值号=的左侧
  • 可以取地址&
  • 变量、对象、数组元素都是左值
    示例:
int x = 10;    //x是左值
x = 20;        //左值可以出现在赋值号=的左侧
int *p = &x;  //可以取地址

在这里插入图片描述

int a=10;
上面这段代码等同于
00007FF631951E6C  mov         dword ptr [a],0Ah 

在这里插入图片描述
对于上面这幅图,我们可以这样理解,左值是有房子的,而右值是住在这个房子里的人
接下来,我们继续深入,我们将代码变换成下面这样

int a=10;a = 20;

在这里插入图片描述
我们来观察这个反汇编代码
其实也就是将原本放10的变换成20,如下图
在这里插入图片描述

2. 右值(Rvalue)

  • 通常没有地址,存储在寄存器或临时内存中
  • 不能出现在赋值号=的左侧
  • 不能取地址&(除非绑定到const左值引用)
  • 字面量、表达式计算结果都是右值
  • 示例:
int a =10 + 5; //(10+5)是右值
10=a;          //❌错误,右值不能在‘ = ’左侧
int &ref = 10; //❌错误,普通引用不能绑定右值
const int &ref = 10;  //✔正确const引用可以绑定右值

对于右值来说,我们可以这样理解,右值是一个没有房子的、孤零零的一个人,这没法改变

int a=10;   //这里的10就是右值,右值没有地址属性的
int& b = a; //引用是变量的别名,这里的b是左值引用,b是一个左值,b有地址属性的

在这里插入图片描述
在这里插入图片描述
也就是下面这样

b = 20; //这里的20就是右值,右值没有地址属性

在这里插入图片描述
rax也就是a的地址

在这里插入图片描述
在这里插入图片描述
还有接下来这种情况

const int &&c = 20; /*右值引用,这里的c就是对右值20的引用,
相当于一个指针指向20,只不过20是一个右值,20没有地址属性*/

在这里插入图片描述
[rbp+64h]是一个栈顶指针,因为此时的20是没有家(也就是地址属性),所以只能用一个临时住所(地址),此时这个20就有了‘家’,但这个家只是临时的,很快就会消失,然后我们将这个指针指向我们的c,c就存储这个右值,称为右值的临时变量。

int a=10;
const int &&c = a;  //这行代码是会报错的
//因为a是一个左值,左值有地址属性,而右值引用只能引用右值,不能引用左值

因为a是一个左值,左值有地址属性,而右值引用只能引用右值,不能引用左值
于是此时我们可以引入C++中的std::move()来解决这个问题

const int&& c = std::move(a);//std::move(a)将a转换为了右值,所以c可以引用a

但此时也出现了一个问题,让我们来看一下汇编代码
在这里插入图片描述
它这里是读取了a的地址,然后让这个c指向这个a,这时我们会不会想起左值引用,是不是一样的???
我们来看看两个的汇编指令代码
在这里插入图片描述
在这里插入图片描述
指令是完全相同的,实际上,这个c也是指向a的指针,和这个b的没有任何的区别,汇编代码都是一样的,这里的move仅仅是将a的性质变了,这个move告诉我们的编译器,现在的这个a是右值了,准确的来说应该是std::move(a)是右值了,这个右值又称为“ 亡值 "(亡值就有了地址).其目的是,可以让这个c在传递参数的时候或者在赋值的时候触发移动构造!!!避免深拷贝。

3. 右值的两种分类

  • 纯右值(PRvalue):真正的右值,如10,x+y
  • 亡值(Xvalue):即将销毁但仍占有资源的对象,如std::move(obj)
类型示例能否取地址?能否赋值?
左值(Lvalue)int x=10;√可以√可以
纯右值(PRvalue)10,x+y❌不能❌不能
亡值(Xvalue)std::move(obj)√可以❌不能

4. 左值引用(Lvaue Reference)

  • 定义:T&绑定到左值
  • 特性:可以修改原变量,不能绑定右值
    示例:
int a=10;
int& b = a;//左值引用绑定左值
b = 20;    //可以修改a

错误示例:

int &ref2=10;//❌错误,右值不能绑定左值引用

5. 右值引用(Rvalue Reference)

  • 定义:T&&绑定右值
  • 特性:用于移动语义,避免拷贝,提高性能
    示例:
int &&ref=10;//✔右值引用绑定右值

不能绑定左值:

int b=20;
int &&ref=b;//❌错误,左值不能被右值引用

std::move()强制转换左值为右值

int &&rref=std::move(b);//✔,b被转换成右值

二、std::move()

1. std::move()的作用

  • 将左值转换成右值,以触发移动语义
  • 不会真正”移动数据“,只是改变对象的属性
  • 用于触发移动构造和移动赋值,避免深拷贝,提高性能
    示例:
#include<iostream>
#include<utility>
#include<string>
using namespace std;
int main()
{string s1="hello";string s2=std::move(s1);//std::move(s1)将s1转换为了右值,所以s2可以引用s1cout<<s1<<endl; //输出空字符串,因为s1已经被移动了,s1的内容已经被转移到了s2中cout<<s2<<endl; //输出helloreturn 0;
}

如果这里的s2没有使用move(),直接使用s1=s2,这实际上就是拷贝构造,触发的是深拷贝;但这也产生了一个问题,如果我们的s1很长,那么我们在拷贝的时候就会浪费很多很多的资源,这就会导致我们的性能下降。。为了避免这个深拷贝带来的资源浪费,我们就很有必要去使用这个move.。
在这里插入图片描述
在这里插入图片描述

2. std::move()的底层原理

std::move()只是static_cast<T&&>,不会改变对象的生命周期

template<typename T>
constexpr remove_reference_t<T>&& move(T&& t) noexcept {return static_cast<remove_reference_t<T>&&>(t);
}

示例:

int a=10;
int &&ref=std::move(a);//ref绑定a的右值引用
  • std::move(e)只是告诉编译器a变成右值,但不会修改a本身
  • ref绑定a的地址,可以继续使用a,但内容可能已经变空
关键字:常用的网络营销的方法_类似互推商盟的推广平台_各大网站收录查询_如何做推广和引流

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: