按值返回的函数无法按预期工作

Function returning by value doesn't work as expected

本文关键字:工作 函数 返回      更新时间:2023-10-16

我是一个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;"语句调试步骤移动到移动构造函数B(B&& other(,我发现这是编译器优化。编译器不使用复制构造函数从本地 B 对象创建 B 对象,而是使用 Move 构造函数。但是,在执行 Move 构造函数后,调试将我带到了析构函数 ~B((。现在,函数返回给 main 的对象消失了。为什么编译器不使用复制 Ctor 然后删除本地对象?谢谢!

为什么编译器不使用 Copy Ctor 然后删除了本地对象?

因为,正如您所观察到的,它改用了移动构造函数。调用移动构造函数,然后销毁本地对象。(当对象超出范围时,将调用析构函数,即使该对象已从中移动。

销毁本地对象时,其ip成员指向的内容将被删除。这通常是好的,除了移动的对象指向相同的事物。您可能希望将移动构造函数设置为other.ip某个有效值。(我通常会建议nullptr,但看起来您的类假设ip永远不会为空。

例如:

B(B&& other) : ip(other.ip){
other.ip = new int(0);
}