【问题标题】:C++: which is the appropriate constructor to be called: the constructor or the copy constructor?C ++:哪个是要调用的适当构造函数:构造函数还是复制构造函数?
【发布时间】:2013-06-12 18:15:56
【问题描述】:

代码

class ElisionTest
{
public:
    int n;
    // ElisionTest(ElisionTest& other): n(other.n) {cout<<"copy constructor"<<endl;}
    ElisionTest(int n): n(n) {cout<<"constructor"<<endl;}
};

int main(int argc, char const *argv[])
{
    ElisionTest et = 10;

}

打印"constructor",这很好。现在,当我取消注释复制构造函数时,我得到一个编译时错误:

cpp_test.cpp: In function 'int main(int, const char**)':
cpp_test.cpp:140:19: error: no matching function for call to 'ElisionTest::ElisionTest(ElisionTest)'
cpp_test.cpp:140:19: note: candidates are:
cpp_test.cpp:135:2: note: ElisionTest::ElisionTest(int)
cpp_test.cpp:135:2: note:   no known conversion for argument 1 from 'ElisionTest' to 'int'
cpp_test.cpp:134:2: note: ElisionTest::ElisionTest(ElisionTest&)
cpp_test.cpp:134:2: note:   no known conversion for argument 1 from 'ElisionTest' to 'ElisionTest& {aka ElisionTest&}'

这可能继续表明这里的复制构造函数将被调用一个临时的ElisionTest(10)。并且由于您不能对临时对象进行非常量引用,因此将复制构造函数的参数设置为 const&amp; 应该可以解决该错误。

但是,如果我将复制构造函数修改为采用const ElisionTest&amp; 而不是ElisionTest&amp;,则不会出现错误,并且输出又是"constructor"。为什么不打印"copy constructor"

【问题讨论】:

  • 你不能有一个临时的非常量引用。
  • @chris:查看更新后的问题

标签: c++ constructor type-conversion copy-constructor copy-elision


【解决方案1】:
ElisionTest(ElisionTest& other);

具有该签名的构造函数允许通过左值初始化ElisionTest 实例。当你这样做时:

ElisionTest et = 10;

这将从临时构造一个ElisionTest 的实例。您的代码相当于:

ElisionTest et = ElisionTest(10);

这将调用你的构造函数,它接受一个非常量引用并用它初始化et。但是非常量引用不能绑定到临时引用。这就是为什么我们需要将const 添加到您的复制构造函数中,以便它可以同时支持左值和右值:

ElisionTest(ElisionTest const& other);
//                      ^^^^^

您看不到任何输出的原因是因为名为 copy-elision 的东西。编译器可以省略对复制/移动构造函数的调用。在 GCC 中,您可以使用 -fno-elide-constructors 关闭复制省略。

【讨论】:

    【解决方案2】:

    它输出"constructor",因为它需要从10 转换为ElisionTest

    它也没有打印"copy constructor",因为它已经被优化掉了(复制省略)。这是唯一可以改变程序可观察行为的优化。

    【讨论】:

    • 所以你是说如果省略掉了,那么输出将是"constructor\ncopy constructor\n"?
    猜你喜欢
    • 1970-01-01
    • 2016-04-02
    • 2016-03-25
    • 2022-11-21
    • 1970-01-01
    • 1970-01-01
    • 2018-10-17
    • 2013-10-13
    • 1970-01-01
    相关资源
    最近更新 更多