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

时间:2013-09-26 04:29:00

标签: 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;}
    };

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

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

关于何时调用复制构造函数,我真的很困惑?就像我运行上面的程序一样,不会调用复制构造函数。这意味着如果我搞乱传递给复制构造函数的参数(消除const关键字),它不应该显示任何编译器错误。但它的表现

  

“没有匹配函数来调用'Test :: Test(Test)'”

此外,fun()返回一个test类型的对象,它在fun()执行期间创建。为什么不在这里调用复制构造函数?

    int main()
    {
        fun();
        return 0;
    }

如果我对主函数进行以下更改,为什么复制构造函数只调用一次,而不是两次?

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

2 个答案:

答案 0 :(得分:6)

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

  

-fno-elide-constructors

在gcc上标记

  

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

或在VS上使用cl /Od program.cpp进行编译(/ O1和/ O2 enables NRVO

C++ : Avoiding copy with the “return” statement

答案 1 :(得分:1)

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

1

Constructor called
fun() Called
Constructor called
Copy constructor called

2

fun() Called
Constructor called
Copy constructor called

3

fun() Called
Constructor called
Copy constructor called
Copy constructor called

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