https://zhuanlan.zhihu.com/p/511371573?utm_medium=social&utm_oi=939219201949429760
下面情况下不会调用:
DPoint3d fun1()
{
return DPoint3d{1,2,3}; // 默认构造
}
int main()
{
DPoint3d&& a = fun1();
a.y = 20;
int i = 0;
++i;
}
下面情况下,会析构:
并且有个警告,说:warning C4172: 返回局部变量或临时变量的地址
注意,是临时变量的“地址”
DPoint3d&& fun1()
{
return DPoint3d{1,2,3}; // 编译:warning C4172: 返回局部变量或临时变量的地址
}
int main()
{
DPoint3d&& a = fun1();
a.y = 20;
int i = 0;
++i;
}
仔细研究下,明明都被析构了,但仍然以右值的名义给带出来了,当然带出来的也是已经析构之后的变量。
但是有一个非常迷惑人的地方,刚出来的时候,还是可以赋值的,但在执行取地址的操作之后,里面的值立刻就现出原型:
struct DPoint3d
{
//! x coordinate
double x;
//! y coordinate
double y;
//! z coordinate
double z;
int*p = nullptr;
DPoint3d()
{
p = new int(5);
std::cout << "DPoint3d" << endl;
}
DPoint3d(double _x, double _y, double _z)
{
p = new int(5);
x = _x;
y = _y;
z = _z;
}
~DPoint3d()
{
delete p;
p = nullptr;
std::cout << this << endl;
std::cout << "~DPoint3d" << endl;
}
DPoint3d(const DPoint3d& pt)
{
std::cout << "123" << endl;
x = pt.x;
y = pt.y;
z = pt.z;
}
DPoint3d(const DPoint3d&& pt)
{
std::cout << "456" << endl;
x = pt.x;
y = pt.y;
z = pt.z;
}
DPoint3d& operator=(DPoint3d&& pt) {
std::cout << "789" << endl;
x = pt.x;
y = pt.y;
z = pt.z;
}
};
DPoint3d fun()
{
DPoint3d a; // 默认构造
a.x = 1;
a.y = 2;
a.z = 3;
// return a; // 报错:无法将左值绑定到右值引用
//return std::move(a); // 返回右值引用,没有进行构造
return a; // 返回右值引用,没有进行构造
}
DPoint3d&& fun1()
{
return DPoint3d{1,2,3}; // 默认构造
}
int main()
{
DPoint3d&& a = fun1();
a.y = 20;
std::cout << &a << endl;
int i = 0;
++i;
}
输出:
0000008F6D7DDA08
~DPoint3d
0000008F6D7DDA08
有个假象,其实对象已经析构了。此时的DPoint3d&& a指向的是一个已经析构过的对象。
从输出结果来看,a和fun1里面的临时 对象的地址都是一样的。
0000008F6D7DDA08
0000008F6D7DDA08
现出真容: