return 在函数中创建的对象。 mingw和cl的区别
return object created in function. mingw and cl difference
我有下一个代码:
#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();
}
Mingw编译程序说:
constructor: 0x22fe4f
foo: 0x22fe4f
destructor: 0x22fe4f
这是我仅使用 wingw
和 g++
编程的预期结果
但是当我尝试使用 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 Constructor
和 Move Constructor
(C++11 之后)可以做同样的事情。
在您的例子中,当执行 return ex
时,函数中创建的实例将被删除,并使用 Copy Constructor
创建一个新实例。如果您编写以下代码,您将获得印刷品
Example(const Example &) {
std::cout << "Copy Constructor" << std::hex << this << std::endl;
}
复制发生在原始对象销毁之前,因此您会在析构函数之前看到此打印。
为什么它不会在某些编译器中发生?
由于称为 RVO(Return 值优化)的机制,编译器会智能地理解您将使用相同的实例,因此它被移动而不是被复制。
希望它澄清。
我有下一个代码:
#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();
}
Mingw编译程序说:
constructor: 0x22fe4f
foo: 0x22fe4f
destructor: 0x22fe4f
这是我仅使用 wingw
和 g++
编程的预期结果
但是当我尝试使用 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 Constructor
和 Move Constructor
(C++11 之后)可以做同样的事情。
在您的例子中,当执行 return ex
时,函数中创建的实例将被删除,并使用 Copy Constructor
创建一个新实例。如果您编写以下代码,您将获得印刷品
Example(const Example &) {
std::cout << "Copy Constructor" << std::hex << this << std::endl;
}
复制发生在原始对象销毁之前,因此您会在析构函数之前看到此打印。
为什么它不会在某些编译器中发生?
由于称为 RVO(Return 值优化)的机制,编译器会智能地理解您将使用相同的实例,因此它被移动而不是被复制。
希望它澄清。