右值引用
概念:左值:有地址的量就是左值。
右值:没有地址量就是右值。
常量因为在寄存器中存储 所以没有地址只有空间。要想引用常量就得 加const
例如 const int & i =10;
同样 我们也可以把它用来处理类对象,当类对象被临时对象初始化时,因为临时对象在代码运行后就会销毁,所以引用失败,虽然加了const 可以解决 const A& a = B(),但是这个对象成员属性我们不能拿来赋值操作。而且常对象只能访问常函数,(实际开发中我们不能要求别人的类成员函数成为常函数)。所以我们把对临时对象的常引用改成右值引用 A&& a = B();,可以延长临时对象存活周期,可以随意访问基类成员函数,可以改写此对象成员属性。具体看代码:
#include <iostream>
using namespace std;
class A
{
public:
A()
{
cout << "A的构造" << endl;
}
A(const A&)
{
cout << "A的拷贝构造" << endl;
}
virtual ~A()
{
cout << "A的析构" << endl;
}
virtual void showInfo()
{
cout << "您 好 啊" << endl;
}
};
class B : public A
{
public:
B()
{
cout << "B的构造" << endl;
}
~B()
{
cout << "B的析构" << endl;
}
void showInfo()override
{
cout << "同学!加油!!!!" << endl;
}
};
int main()
{
// const int& a = 10; //int temp = 10, const int& = temp;
//左值引用也叫常引用。
// const A& a = B();
A&& a = B();//右值引用应用场景之一 临时对象触发多态
a.showInfo();
//用了右引用之后就不会只能访问常函数了
//而且 这个对象也可以被赋值了 体现在移动构造
A&& a1 = std::move(a);//用已有的对象来初始化对象 move 其实返回的是临时对象 触发多态
a1.showInfo();
return 0;
}
移动语义函数std::move(左值)使用:主要是用来移动左值的空间资源的。
#include <iostream>
using namespace std;
class A
{
private:
int* p;
public:
A():p(new int[1024])
{
cout << "A的构造" << endl;
}
A(const A& other)
{
this->p = new int[1024];
memcpy(this->p,other.p,sizeof(int[1024]));
cout << "A的拷贝构造" << endl;
}
A(A&& other)//之所以传入的是右值引用就是因为 内部实现要对传进来的参数 进行操作
{
this->p = other.p;
other.p = nullptr;
cout << "A的移动构造" << endl;
}
~A()
{
if(p != nullptr)
{
delete [] p;
p = nullptr;
}
cout << "A的析构" << endl;
}
};
int main()
{
A a;
A a1 = std::move(a);//提高拷贝构造的效率 其实是隐构造 如果不写移动构造 调用的是拷贝构造
//A&& a1 = std::move(a); 其实也是起别名
}
*‘=’运算符在c++编程中有隐式构造;具体可以看我在c++之类对象中的的介绍,赋值运算就是普通的赋值;多态的一种类型,父类指针指向子类对象天然且安全。*这三种意思。大家在看代码时要注意分析。