C++ 为什么这里不调用复制构造函数?

C++ 为什么这里不调用复制构造函数?,c++,copy-constructor,C++,Copy Constructor,对于以下代码: #include<iostream> using namespace std; class Test { public: Test(const Test &t) { cout<<"Copy constructor called"<<endl;} Test() { cout<<"Constructor called"<<endl;}

对于以下代码:

    #include<iostream>
    using namespace std;

    class Test
    {
    public:
       Test(const Test &t) { cout<<"Copy constructor called"<<endl;}
       Test()        { cout<<"Constructor called"<<endl;}
    };

    Test fun()
    {
        cout << "fun() Called\n";
        Test t;
        return t;
    }

    int main()
    {
        Test t1;
        Test t2 = fun();
        return 0;
    }
另外,如果我对主函数进行以下更改,为什么复制构造函数只调用一次,而不是两次

    int main()
    {
        Test t2 = fun();
        Test t3 = t2;
        return 0;
    }

当我在VS2010中运行您的代码时,我得到了正确的结果:

一,

二,

三,


已正确调用复制构造函数。

在VS2010中运行代码时,我得到了正确的结果:

一,

二,

三,


已正确调用复制构造函数。

这是因为此处使用的是复制初始化,而不是复制构造函数,这是由于编译器中启用了复制构造函数。您应该指定

-fno elide构造函数

海合会旗帜

C++标准允许实现省略创建临时性 它仅用于初始化同一类型的另一个对象。 指定此选项将禁用该优化,并强制G++ 在所有情况下都调用复制构造函数

或者使用VS(/O1和/O2)上的
cl/Od program.cpp
编译它


这是因为这里使用的是复制初始化,而不是复制构造函数,这是由于编译器中启用了。您应该指定

-fno elide构造函数

海合会旗帜

C++标准允许实现省略创建临时性 它仅用于初始化同一类型的另一个对象。 指定此选项将禁用该优化,并强制G++ 在所有情况下都调用复制构造函数

或者使用VS(/O1和/O2)上的
cl/Od program.cpp
编译它


复制构造函数的可能副本在VC++2013 RC上按预期被调用。@xmllmx:即使在发布模式下?因为如果在上有优化的现代编译器上,这实际上是不可能的。正如@BenjaminLindley指出的,当使用-fno elide构造函数编译时,复制构造函数将被调用。@Benjamin,不。它不会在发布模式下被调用,正如您所指出的。复制构造函数的可能副本在VC++2013 RC上按预期调用。@xmllmx:即使在发布模式下也是如此?因为这实际上是不可预期的,如果在现代编译器上有优化。正如BenjaminLindley指出的,当用-FNO-ELID构造函数编译时,调用复制构造函数。@本杰明,不。它不会在发布模式下被调用,正如你指出的。但是在IDEND和DEV C++中,它并没有像预期的那样显示结果。为什么会这样?虽然说这些是不正确的结果是错误的,但它们并不是唯一正确的结果。然而,它们通常不是理想的结果。如果这些是启用优化的结果(我怀疑它们不是),那么这是VS2010编译器的一个缺陷,即使结果在技术上是正确的。但是在IDENN和DEV C++中,它没有显示出预期的结果。为什么会这样?虽然说这些是不正确的结果是错误的,但它们并不是唯一正确的结果。然而,它们通常不是理想的结果。如果这些是启用了优化的结果(我怀疑不是),那么这就是VS2010编译器的缺陷,即使结果在技术上是正确的。
    int main()
    {
        Test t2 = fun();
        Test t3 = t2;
        return 0;
    }
Constructor called
fun() Called
Constructor called
Copy constructor called
fun() Called
Constructor called
Copy constructor called
fun() Called
Constructor called
Copy constructor called
Copy constructor called