返回在函数中创建的对象

return object created in function. mingw and cl difference

本文关键字:对象 创建 函数 返回      更新时间:2023-10-16

我有下一个代码:

#include <iostream>
class Example
{
public:
Example()
{
std::cout
<< "constructor: "
<< std::hex
<< this
<< std::endl;
}
~Example()
{
std::cout
<< "destructor:  "
<< std::hex
<< this
<< std::endl;
}
static Example foo()
{
Example ex;
std::cout
<< "foo:         "
<< std::hex
<< &ex
<< std::endl;
return ex;
}
};

int
main()
{
Example ex = Example::foo();
}

明武编译程序 说: constructor: 0x22fe4f foo: 0x22fe4f destructor: 0x22fe4f

这是我只用wingwg++编程的预期结果 但是当我尝试使用Microsoft cl时,我得到了这个: constructor: 00000000001BF750 foo: 00000000001BF750 destructor: 00000000001BF750 destructor: 00000000001BF790

两个析构函数调用?只有一个构造函数调用?好的,foo创建自己的对象并在return上调用copy构造函数。但是,当编译器可以将对象放入像 mingw 这样的函数堆栈中main并将out指针作为函数本身foo参数时,为什么我需要复制它? 喜欢这个:

// no return but `out` reference
static void foo(Example &ex)
{
std::cout
<< "foo:         "
<< std::hex
<< &ex
<< std::endl;
}
};

int
main()
{
Example ex; // allocate memory in stack
Example::foo(ex); // process/fill it
}

我做错了什么,或者有什么方法可以不调用copy构造函数并且不使用out引用编写代码?

构造函数不是创建对象的唯一方法。Copy ConstructorMove Constructor(C++11 起(也可以这样做。

在您的情况下,执行return ex时,将删除在函数中创建的实例,并使用Copy Constructor创建新实例。 如果您编写以下代码,您将获得打印

Example(const Example &) {
std::cout << "Copy Constructor" << std::hex << this << std::endl;
}

复制发生在原始对象销毁之前,因此您将在析构函数之前看到此打印。

为什么它在某些编译器中没有发生?

由于一种称为 RVO(返回值优化(的机制,编译器可以智能地理解您将使用相同的实例,因此它被移动而不是被复制。

希望它澄清。