C++ 为什么复制构造函数要在C+;中通过引用接受其参数+;?
为什么复制构造函数的参数必须通过引用传递?因为如果不是通过引用传递,则是通过值传递。为此,您创建了一个副本,并为此调用了复制构造函数。但要做到这一点,我们需要创建一个新值,所以我们调用复制构造函数,等等C++ 为什么复制构造函数要在C+;中通过引用接受其参数+;?,c++,constructor,copy,copy-constructor,C++,Constructor,Copy,Copy Constructor,为什么复制构造函数的参数必须通过引用传递?因为如果不是通过引用传递,则是通过值传递。为此,您创建了一个副本,并为此调用了复制构造函数。但要做到这一点,我们需要创建一个新值,所以我们调用复制构造函数,等等 (您将具有无限递归,因为“要创建副本,您需要创建副本”。因为pass-by-value将调用复制构造函数:)如果您按值传递它,它将是无限递归的。传递值实际上是传递副本。复制构造函数是制作副本所必需的 如果为了调用复制构造函数而必须进行复制,这将是一个难题 (我认为无限递归会发生在编译器中,你永远
(您将具有无限递归,因为“要创建副本,您需要创建副本”。因为pass-by-value将调用复制构造函数:)如果您按值传递它,它将是无限递归的。传递值实际上是传递副本。复制构造函数是制作副本所必需的 如果为了调用复制构造函数而必须进行复制,这将是一个难题 (我认为无限递归会发生在编译器中,你永远不会得到这样一个程序。) 除合理原因外,§12.8/3中的标准禁止: 函数的构造函数的声明 如果类X的第一个 参数的类型为(可选为cv)- 合格)X,并且没有 其他参数或其他所有参数 参数具有默认参数
无论何时调用函数(例如:intf(carc)) 它接受的参数不是内置的数据类型(这里是car) 复制调用方提供的实际对象的要求 调用函数参数中的变量。
例如:
carobj;
f(carobj)代码>
也就是说,将carobj
复制到c
carobj
需要复制到函数f
中的参数c
为了实现复制,调用复制构造函数
在这种情况下,使用传递值调用函数f
,或者换句话说,函数f
被声明为接受传递值
如果函数f
通过引用传递,则其声明为
intf(car&c)代码>
在这种情况下,
carobj;
f(carobj)代码>
不需要复制构造函数
在这种情况下,c
成为carobj
的别名
使用上述两种情况,为便于澄清,我将其总结为:
如果函数声明以参数作为对象的值,则调用该对象的复制构造函数
如果函数声明将参数作为“按引用传递”,则该参数将成为调用者提供的对象的别名。不需要复制构造函数
现在的问题是为什么需要通过引用传递。如果复制构造函数接受引用,则接收变量将成为所提供对象的别名。因此,不需要复制构造函数(在本例中是对自身的调用)将调用者提供的对象中的值复制到参数列表中的构造函数变量
否则,如果复制构造函数将调用方提供的对象作为值,即传递值,则需要给定对象的复制构造函数;因此,要将调用方提供的对象放入函数本身(在本例中为复制构造函数),我们需要调用复制构造函数,它只是在函数声明期间调用同一个函数
这就是将引用传递给副本构造函数的原因。将对象作为引用传递是非常必要的。如果将对象作为值传递给复制构造函数,则其复制构造函数将调用自身,将实际参数复制到形式参数。
因此,将启动对复制构造函数的无休止的调用链。此过程将一直持续到系统内存耗尽
因此,在复制构造函数中,参数应始终作为引用传递。如果它不是通过引用传递的,则它将通过值传递。如果参数是按值传递的,则其复制构造函数将调用自身将实际参数复制到形式参数。这个过程将一直持续到系统内存不足为止。
所以,我们应该通过引用传递它,这样复制构造函数就不会被调用 有必要将对象作为引用传递,而不是按值传递,因为如果按值传递,则其副本是使用复制构造函数构造的。这意味着复制构造函数将调用自身进行复制。此过程将一直进行,直到编译器内存耗尽。编译器可以愉快地抛出无限递归;我怀疑这不是特例。但是,如果使用非引用参数声明副本构造函数,则程序的格式不正确。所以你说它不应该编译是对的。@Dennis:我的意思是,如果你试图编译这样一个程序,编译器在试图生成代码时会陷入困境。它不会生成递归函数,因为这个难题发生在函数调用之前,在调用方中。不管怎样,无论您是否尝试使用它,程序都是格式错误的。简单地定义构造函数就足以让编译器对你大喊大叫。@Dennis:的确,尽管这只是一条规则。有没有理由不能通过指针传递到实例?那么它就不再是复制构造函数了,但是只是一个普通的旧构造函数,它碰巧接受一个指针。@巴里当编译器试图通过调用object o(other\u object)
来自己复制一个对象时,通常会实现一个复制构造函数。但只有当对象
有一个构造函数通过值或引用获取另一个对象时,这才有效。您已经知道为什么按值传递不起作用,所以唯一的方法是按引用或常量引用传递。如果您的“复制构造函数”将获取指向对象的指针
,那么编译器的代码必须是对象o(&other_object)
。因此,本质上,您编写的构造函数满足编译器和用户的期望。是的,这是完全有意义的。谢谢。另一个很好的理由,由