1

对于以下代码:

    #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;
    }
4

2 回答 2

6

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

-fno-elide-constructors

gcc 上的标志

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

或在 VS 上编译它cl /Od program.cpp(/O1 和 /O2启用 NRVO

C++:使用“return”语句避免复制

于 2013-09-26T04:48:03.433 回答
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

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

于 2013-09-26T04:42:19.317 回答