假设我有:
class A
{
A(A& foo){ ..... }
A& operator=(const A& p) { }
}
...
A lol;
...
A wow(...)
{
return lol;
}
...
...
A stick;
stick = wow(...);
然后我会在最后一行得到编译错误。但是如果我在'A&'之前添加'const',那就ok了。
我想知道原因。这究竟是什么问题? 我不明白为什么它应该是常量。
语言:C ++
我编辑过...我认为改变它的相关性。这给出了错误。
答案 0 :(得分:1)
以下代码与Comeau和VC9完全匹配:
class A
{
public:
A() {}
A(A&){}
};
A lol;
A wow()
{
return lol;
}
int main()
{
A stick;
stick = wow();
return 0;
}
如果这不能用你的编译器编译,那么我怀疑你的编译器坏了。如果确实如此,则表示您应该粘贴实际代码,而不是提供与您看到的问题不相似的代码段。
答案 1 :(得分:1)
对wow
的调用会产生一个临时对象,一个r值。 R值不能分配给非const引用。由于您的复制构造函数接受非const引用,因此您无法将调用结果直接传递给wow
。这就是添加const
修复问题的原因。现在复制构造函数接受const引用,r值绑定到就好了。
很可能,您的复制构造函数不会更改它正在复制的对象,因此该参数应该通过const-reference传递。这是复制构造函数的工作方式,除非在特定的,记录的情况下。
但是正如sbi在他的回答中指出的那样,这个拷贝构造函数根本不应该被调用。所以虽然这一切都是真的,但它可能与你的问题无关。除非有编译器错误。也许你的编译器看到了两步构造,并决定通过将A stick; stick = wow();
转换为A stick = wow();
来切断中间人但是这将是一个错误,因为它产生了一个编译的事实证明了完全合法的代码错误。但如果没有实际的代码,就无法说出真正发生的事情。在您的复制构造函数出现任何问题之前,应该有其他几个错误。
答案 2 :(得分:1)
我相信你提到的问题类似于:
c++, object life-time of anonymous (unnamed) variables
其中要点是在C ++中匿名临时值不能通过引用传递,而只能通过const引用传递。
答案 3 :(得分:0)
不可重现。您是否缺少默认构造函数,或者忘记构造构造函数public
?
请参阅http://www.ideone.com/nPsHj。
(注意,复制构造函数可以使用任何const-volatile组合加上一些默认参数的cv A&
参数。参见C ++标准中的§[class.copy] / 2。 )
编辑:有趣的是,g ++ - 4.3(ideone)和4.5(带有-pedantic
标志)没有编译错误,但是g ++ - 4.2会抱怨:
x.cpp: In function ‘int main()’:
x.cpp:19: error: no matching function for call to ‘A::A(A)’
x.cpp:7: note: candidates are: A::A(A&)
答案 4 :(得分:0)
此功能:
A wow(...)
{ ... }
返回按值的对象 这意味着它被复制回函数被调用的位置。
这一行:
stick = wow(...);
棒上是否有复制结构
复制到stick中的值是从函数wow()复制回来的值。
但请记住,调用wow()的结果是一个临时对象(它是从wow()复制回来的,但还不是变量)。
现在我们来看看A:
的复制构造函数A(A& foo){ ..... }
您正在尝试将临时对象传递给引用参数。这是不允许的。临时对象只能绑定到const引用。该问题有两种解决方案:
1)使用const引用 2)将值传递给复制构造函数。
不幸的是,如果你使用解决方案(2),你会变得有点卡住,因为它变成了循环依赖。按值传递涉及使用复制构造函数,因此您输入infinte循环。所以你的解决方案是使用pass by const reference。