【问题标题】:Is there any difference between copy constructor/copy assignment and normal function call optimization in compiling?复制构造函数/复制赋值和编译中的普通函数调用优化有什么区别吗?
【发布时间】:2016-06-21 12:10:35
【问题描述】:

我在测试一个小例子时遇到了一个有趣的编译错误:

#include <iostream>

using namespace std;

class A
{
public:
   A() { cout <<"A created." <<endl; }
   A(A& a) { cout <<"A created by copy constructor." <<endl; }
   ~A() { cout <<"A destoryed." <<endl; }
};

A CreateObject()
{
    A obj;
    return obj;
}   

int main()
{
    A a;
    A b;

    b= CreateObject();

    return 0;
}

这很简单,可能根本没有任何问题。但是,它在编译时提示:

copy_constructor.cpp: In function ‘int main()’:
copy_constructor.cpp:23: error: no matching function for call to ‘A::A(A)’
copy_constructor.cpp:9: note: candidates are: A::A(A&)

似乎程序在编译“b= CreateObject();”时尝试调用复制构造函数但没有匹配的复制构造函数。这不应该发生,因为它只是一个赋值语句,构造函数和普通函数在编译优化上有什么区别?

【问题讨论】:

  • 为我编译:coliru.stacked-crooked.com/a/019cc3c18ba2a889。你的编译器和编译选项是什么?
  • 复制构造函数应该采用const 引用,而不是可修改的引用。
  • 你确定你的真实代码实际上不是A b = CreateObject();吗?
  • 这不是拷贝赋值而不是拷贝构造函数吗?
  • @Petr 谢谢!看来你可以很好地编译它。我使用带有“g++ a.cpp -o a”的 g++ 来编译代码,但结果不同,我的编译器信息:g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-50) 版权所有 (C) 2006 Free Software Foundation, Inc. 这是免费软件;查看复制条件的来源。没有保修;甚至不是为了适销性或适合特定目的。

标签: c++ compilation


【解决方案1】:
A(A& a) { cout <<"A created by copy constructor." <<endl; }
...
b = CreateObject();

根据 C++03 标准,这是无效的。

在 C++03 中,b = CreateObject() 实际上可以扩展为 b = A(CreateObject());。这仅在更高版本的 C++ 中“修复”,现在禁止创建临时副本。

CreateObject() 返回一个 r-hand 值,该值只能由具有 A(const A&amp; a) 签名的复制构造函数使用。如果没有 const 修饰符,它只适用于左手值。

例如b = a 对于该签名和扩展仍然有效,因为您可以在构造函数中修改 a


将 clang++ 设置为 C++98 标准仍然是可复制的:http://coliru.stacked-crooked.com/a/50c25c469420ab0f

旧版本的 Visual-C++ 显示 OP 显示的精确错误。

g++ 无法正确验证这一点,即使明确指定 C++98。

另见https://stackoverflow.com/a/13898867/2879325

【讨论】:

  • 您找到了根本原因,确实我从您的回答中学到了很多东西。谢谢! :)
【解决方案2】:

您发布的代码编译得很好。但是,您应该将复制构造函数从 A(A&amp;) 更改为 A(const A&amp;)

【讨论】:

  • 谢谢! @Zwinck,您的解决方案将A(A&amp;) 更改为A(const A&amp;) 确实有效。我用@Ext3h 的解释弄清楚了这一点。
猜你喜欢
  • 2012-07-27
  • 1970-01-01
  • 2014-05-18
  • 2017-12-23
  • 2015-03-03
  • 1970-01-01
  • 2020-01-09
  • 2016-11-26
  • 1970-01-01
相关资源
最近更新 更多