目录
将亡值
在栈上只调用类中构造函数的对象叫做临时对象,这个对象只有空间在栈上而没有地址,临时对象没有地址,所以他的生命周期非常短暂,在发生传递之后就被销毁了。
类型 a = 类型中的构造函数() //这种形式就是使用一个临时对象为本对象进行初始化。
比如:A a = A();
右值引用
右值引用的语法:
类型&& 变量 = 临时变量(常量)
1.右值引用只能引用右值,不能引用左值
2.当父类的右值引用引用了一个子类的临时对象,也是可以发生多态的
3.使用右值引用可以避免const修饰的左值引用的必须在类中成员函数后加const的问题,而无需修改源码。
移动构造
类名(类型&& other)
{
this->资源 = other.资源
other.资源 = nullptr;
}
将自身资源赋值给别人后,自身指向nullptr。
综合代码
定义一个父类:
#include <iostream>
using namespace std;
class A
{
public:
A()
{
cout << "A的构造" << endl;
}
A(const A& other)
{
cout << "A的拷贝构造" << endl;
}
A(A&& other)
{
cout << "A的移动构造" << endl;
}
virtual ~A()
{
cout << "A的析构 " << endl;
}
virtual void showInfo()
{
cout << "同学们加油哦" <<endl;
}
};
定义一个子类:
class B : public A
{
private:
int *p;
public:
B() : p(new int [1024])
{
cout << "B的构造: " << endl;
}
~B()
{
if(p != nullptr)
{
delete []p;
}
cout << "B的析构" << endl;
}
B(const B& other)
{
this->p = new int [1024];
memcpy(this->p, other.p, sizeof (int [1024]));
cout << "B的拷贝构造" << endl;
}
B(B&& other)
{
this->p = other.p;
other.p = nullptr;
cout << "B的移动构造" << endl;
}
void showInfo() override
{
cout << "同学加油 " << endl;
}
};
主函数验证:
int main()
{
// //正常使用
// A * a = new B();
// a->showInfo();
// delete a;
cout << "-----------------------------------------------------------" << endl;
//这里的B()是将亡值
// A a = B();
// a.showInfo();
// A& a1 = B(); //报错,将亡值,也叫临时对象,这种临时对象也被称为右值,不能引用右值
cout << "-----------------------------------------------------------" << endl;
//解决方法1:
// const A& a1 = B();
// a1.showInfo();
// //更改父类为常函数 void showInfo() const
// //更改子类为常函数 void showInfo() const override
// 本质是:B temp = B(); const A& a1 = temp;
cout << "-----------------------------------------------------------" << endl;
//解决方法2:
//const A& a1 = B();
//const_cast<A&>(a1).showInfo(); //使用强转
cout << "-----------------------------------------------------------" << endl;
//解决方式3: 右值引用
//从const修饰的左值引用,升级为右值引用,右值引用可以锁定将亡值
//A&& a2 = B();
//a2.showInfo();
cout << "-----------------------------------------------------------" << endl;
//方法4: 移动构造
//B a1 = B();
//B&& a3 = std::move(a1);
//使用移动语义函数 std::move(左值), 此方法,会将原对象的空间直接给新对象用,即新旧指向同一片空间
//a3.showInfo();
//a1.showInfo();
//cout << &a3 << endl; //0x61fdf0
//cout << &a1 << endl; //0x61fdf0
return 0;
}
运行结果:
读者可复制代码,逐个解注释,查看运行效果。