我是C ++新手。我了解到一个函数可以按值返回,但是在我的代码中它似乎无法正常工作。
#include "pch.h"
#include <iostream>
class B {
public:
int* ip;
B() : ip(new int(0)) {}
//COPY CTOR
B(B& other){
ip = new int(0);
*ip = *other.ip;
}
//MOVE CTOR
B(B&& other) : ip(NULL){
ip = other.ip;
}
B& operator=(B& other)
{
int* ptr = new int(0);
*ptr = *other.ip;
delete ip;
ip = ptr;
}
B& operator=(B&& other)
{
int* ptr = new int(0);
*ptr = std::move(*other.ip);
delete ip;
ip = ptr;
}
~B() {
delete ip;
ip = NULL;
}
};
B CreateB()
{
B b;
*(b.ip) = 99;
return b;
}
int main()
{
B BObj(CreateB());
std::cout << "B.ip=" << *BObj.ip << std::endl;
system("pause");
return 0;
}
我在调试模式下使用Visual Studio 2019,我进入CreateB()并发现创建了本地对象B.在“ return b;”处语句调试步骤移至Move Constructor B(B && other),我发现这是编译器优化。编译器没有使用Copy构造函数从本地B对象创建B对象,而是使用Move Constructor。但是,执行Move构造函数后,调试使我进入了析构函数〜B()。现在,函数返回给main的对象消失了。为什么编译器不使用Copy Ctor然后删除本地对象?谢谢!
答案 0 :(得分:3)
为什么编译器不使用Copy Ctor然后删除本地对象?
因为,正如您所观察到的,它改用了move构造函数。调用move构造函数,然后销毁了本地对象。 (当对象超出范围时,即使该对象已移出,也会调用析构函数。)
销毁本地对象后,其ip
成员指向的对象被删除。这通常是好的,除了被移动的对象指向相同的东西。您可能希望将自己的移动构造函数设置为other.ip
某个有效值。 (我通常建议使用nullptr
,但是您的类似乎假设ip
永远不会为null。)
例如:
B(B&& other) : ip(other.ip){
other.ip = new int(0);
}