复制构造函数,为什么通过值函数返回

时间:2010-04-25 07:48:18

标签: c++ const copy-constructor

假设我有:

class A
{
    A(A& foo){ ..... }
    A& operator=(const A& p) {  }
}

...
A lol;
...

A wow(...)
{

    return lol;
}

...
...
A stick;
stick = wow(...);

然后我会在最后一行得到编译错误。但是如果我在'A&'之前添加'const',那就ok了。

我想知道原因。这究竟是什么问题? 我不明白为什么它应该是常量。

语言:C ++

我编辑过...我认为改变它的相关性。这给出了错误。

5 个答案:

答案 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。