在测试一个小例子时遇到了一个有趣的编译错误:
#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();”时试图调用复制构造函数但是没有匹配的拷贝构造函数。这不应该发生,因为它只是一个赋值语句,编译优化中构造函数和普通函数之间有什么区别吗?
答案 0 :(得分:2)
A(A& a) { cout <<"A created by copy constructor." <<endl; }
...
b = CreateObject();
根据C ++ 03标准,这是无效的。
在C ++ 03中,b = CreateObject()
实际上可能会扩展为b = A(CreateObject());
。这只是&#34;固定&#34;在C ++的更高版本中,现在禁止创建临时副本。
CreateObject()
返回一个r-hand值,该值只能由具有A(const A& a)
签名的复制构造函数使用。如果没有const
修饰符,它只适用于l-hand值。
E.g。 b = a
对于该签名和扩展仍然有效,因为您可以在构造函数中修改a
。
这仍然是可复制的设置clang ++到C ++ 98标准:http://coliru.stacked-crooked.com/a/50c25c469420ab0f
较早版本的Visual-C ++显示OP显示的精确错误。
g ++无法正确验证这一点,即使在明确指定C ++ 98时也是如此。
答案 1 :(得分:0)
您发布的代码编译得很好。但是,您应该将复制构造函数从A(A&)
更改为A(const A&)
。