GMa*_*ckG 173

因为如果它不是通过引用,它是按价值的.要做到这一点,你做一个副本,并为此,你调用复制构造函数.但要做到这一点,我们需要创建一个新值,所以我们调用复制构造函数,依此类推......

(你会有无限的递归,因为"要制作副本,你需要制作副本".)

  • 然后它不再是一个复制构造函数,而只是一个接受指针的常规旧构造函数. (22认同)
  • @Barry当编译器试图通过调用`object o(other_object)`来创建一个对象的副本时,你通常会实现一个拷贝构造函数.但是这只有在`object`有一个构造函数通过值或引用获取另一个`object`时才有效.你已经知道为什么传递值不起作用,所以唯一的方法是通过引用或const引用传递.如果你的"copy-constructor"会指向一个`object`,那么编译器的代码必须是`object o(&other_object)`.所以从本质上讲,你编写的构造函数可以满足编译器和用户的期望. (6认同)

Bri*_*ach 65

因为pass-by-value会调用复制构造函数:)


Pot*_*ter 21

pass-by-reference的替代方法是pass-by-value.按值传递实际上是逐个复制的.复制构造函数需要进行复制.

如果你不得不复制只是为了调用复制构造函数,那将是一个难题.

(我认为无限递归会在编译器中发生,你实际上从来没有得到过这样的程序.)

除了合理的原因,§12.8/ 3中的标准禁止它:

如果类X的构造函数的第一个参数是类型(可选地是cv-限定的)X并且没有其他参数或者所有其他参数都具有默认参数,那么它的构造函数的声明是错误的.


Rom*_*eau 12

如果你通过值传递它将是无限递归


小智 8

每当你调用一个函数(例如:int f(car c))它的参数不是内置数据类型(这里是 car)时,需要将调用者提供的实际对象复制到被调用函数参数中的变量。
例子:

car carobj; f(carobj);

也就是说,复制carobjc.

carobj需要复制到c函数中的参数f

为了实现复制,调用了复制构造函数。

在这种情况下,f使用按值传递调用的函数或换句话说,函数f被声明为按值传递。

如果函数f通过引用传递,那么它的声明是 int f(car &c);

在这种情况下,
car carobj; f(carobj);

不需要复制构造函数。

在这种情况下,c成为 的别名carobj

使用上述 2 个场景,为了您的清晰起见,我将它们总结为:

  1. 如果函数被声明为将参数作为对象的值,则调用该对象的复制构造函数。

  2. 如果函数被声明为采用“通过引用传递”的参数,则该参数将成为调用者提供的对象的别名。不需要复制构造函数!

现在的问题是为什么需要通过引用传递。如果复制构造函数接受引用,则接收变量将成为所提供对象的别名。因此,不需要复制构造函数(在这种情况下,调用自身)将调用者提供的对象中的值复制到参数列表中复制构造函数的变量。

否则,如果复制构造函数将调用者提供的对象作为值,即传值,那么它需要给定对象的复制构造函数;因此,为了从调用者那里获取提供的对象到我们的函数本身(在这种情况下是复制构造函数),我们需要调用复制构造函数,它只是在函数声明期间调用相同的函数。

这就是将引用传递给复制构造函数的原因。

  • 虽然你是对的,但已经有四个答案解释了这一点,而且做得更清楚。我不明白你为什么认为这个问题的第五个答案会有所帮助。 (4认同)

ana*_*thi 6

有必要将对象作为引用而不是按值传递,因为如果按值传递它的副本是使用复制构造函数构造的。这意味着复制构造函数将调用自身进行复制。此过程将一直持续到编译器运行完毕的记忆。