返回在函数中创建的对象。 mingw和cl差异

时间:2018-06-08 06:01:54

标签: c++ return mingw cl

我有下一个代码:

#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

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

两个析构函数调用?只有一个构造函数调用?好的,foo创建了自己的对象,并在copy上调用return构造函数。但是为什么我需要在编译器将对象放入main函数堆栈中时复制它,如mingw并将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引用来编写代码?

1 个答案:

答案 0 :(得分:0)

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

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

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

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

为什么在某些编译器中没有发生这种情况?

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

希望它澄清。