创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!!
主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!
🔥c++系列专栏:C/C++零基础到精通 🔥给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ
一、左值和右值
引用可以分为左值引用,右值引用,常引用
左值:
- 可以出现在赋值号左和右的值
- 可以取地址、修改、起名
例如:变量、指针、对象
右值:
- 只能出现在赋值号右面
- 不可取地址、修改、起名
例如:常量、函数返回值、表达式返回值
常引用可以接受左值也可以接受右值,但是不可以修改引用的值
左值引用:给变量起别名,使用 &
定义,定义了引用就要初始化,不存在空的引用!左值引用知识点:引用的概念和用法
右值引用:用 &&
符号引用右值
左值引用和右值引用定义举例:
#include <iostream>
#include <string>
using namespace std;
class A
{
public:
A();
void fun()
{
cout << "A::fun()" << endl;
}
~A();
};
int main()
{
A a;
A &a1 = a; //左值引用
A &a2 = A(); //error:不能绑定右值 A()
A &&a3 = a; //error:不能绑定左值 对象a
A &&a4 = A();//右值引用
A &&a5 = std::move(a);//将左值转移语义为右值后右值引用
return 0;
}
右值引用可以将 A()
表达式 临时对象延长生命周期
二、完美转发
将一组参数原封不动地传递给另一个函数,转发左值,另一个函数中接收的就是左值,右值同理,使用 std::forward()
实现。
在C++11之前,常引用(const T&)被用于函数参数,以允许函数接受左值(lvalue)和右值(rvalue)作为参数,同时保证函数内部不会修改这个值。但是并没有明确区分左值和右值,函数传参时无法区分
在C++11之后的版本中,引入了右值引用的概念(T&&),允许更明确地处理左值和右值,可以将常引用与右值引用传参时进行区分。
三、移动语义
转移语义可以将资源(堆,系统对象等)从一个对象转移到另一个对象,这样能够减少不必要的临时对象的创建、拷贝以及销毁,能够大幅度提高C++ 应用程序的性能。在某些情况下可以进行对象赋值而避免深拷贝。
std::move
可以将左值强制转换成右值
智能指针中可以使用 std::move
将空间的使用权转交给另一个智能指针,而无需拷贝
unique_ptr<A> p1(new A());
unique_ptr<A> p2;
p2 = std::move(p1); //使用权传递,不可以直接使用 = 赋值
(*p2).fun();
移动语义只有 对于实现了移动构造函数的类对象才起作用
减少拷贝开销
移动语义举例:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<int> fun()
{
vector<int> res;
for (int i = 1; i <= 10000;i++)
{
res.push_back(i);
}
return res; //返回将亡值 编译器会自动考虑是否使用移动语义:调用移动构造,触发移动语义
}
int main()
{
vector<int>&& res = fun(); //显式右值引用
for (const auto& ite : res) //常引用,避免拷贝
{
cout << ite << " ";
}cout << endl;
return 0;
}
大家的点赞、收藏、关注将是我更新的最大动力! 欢迎留言或私信建议或问题。 |
大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!如果本文哪里有错误的地方还请大家多多指出(●'◡'●) |