为什么复制构造函数要在 C++ 中通过引用接受其参数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2685854/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:21:25  来源:igfitidea点击:

Why should the copy constructor accept its parameter by reference in C++?

c++constructorcopycopy-constructor

提问by Jony

Why must a copy constructor be passed its parameter by reference?

为什么必须通过引用传递复制构造函数的参数?

回答by GManNickG

Because if it's not by reference, it's by value. To do that you make a copy, and to do that you call the copy constructor. But to do that, we need to make a new value, so we call the copy constructor, and so on...

因为如果不是按引用,则是按值。为此,您创建一个副本,然后调用复制构造函数。但是要做到这一点,我们需要创建一个新值,因此我们调用复制构造函数,依此类推……

(You would have infinite recursion because "to make a copy, you need to make a copy".)

(您将有无限递归,因为“要制作副本,您需要制作副本”。)

回答by Brian Roach

Because pass-by-value would invoke the copy constructor :)

因为按值传递会调用复制构造函数:)

回答by Potatoswatter

The alternative to pass-by-reference is pass-by-value. Pass-by-value is really pass-by-copy. The copy constructor is needed to make a copy.

按引用传递的替代方法是按值传递。按值传递实际上是按复制传递。复制构造函数需要复制。

If you had to make a copy just to call the copy constructor, it would be a conundrum.

如果为了调用复制构造函数而必须进行复制,那将是一个难题。

(I think the infinite recursion would occur in the compiler and you'd never actually get such a program.)

(我认为无限递归会发生在编译器中,而您实际上永远不会得到这样的程序。)

Besides rationalreasons, it's forbidden by the standard in §12.8/3:

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

A declaration of a constructor for a class X is ill-formed if its first parameter is of type (optionally cv- qualified) X and either there are no other parameters or else all other parameters have default arguments.

如果类 X 的第一个参数是类型(可选 cv 限定的)X 并且没有其他参数或所有其他参数都有默认参数,则类 X 的构造函数声明是格式错误的。

回答by Romain Hippeau

It would be infinitely recursive if you passed it in by value

如果按值传入,它将是无限递归的

回答by Sriraman

whenever you call a function (example: int f(car c)) which takes its arguments other than built-in data types (here car) a requirement to copy the actual object supplied by the caller to the variable in the called function's parameter.
example:

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

car carobj; f(carobj);

car carobj; f(carobj);

that is, copy carobjto c.

也就是说,复制carobjc.

carobjneeds to be copied to the parameter cin function f.

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

To achieve copying, the copy constructor is called.

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

In this case, function fcalled using pass by value or in other words, function fis declared to take pass by value.

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

If function ftakes pass by reference, then its declaration is int f(car &c);

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

In this case,
car carobj; f(carobj);

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

does not need a copy constructor.

不需要复制构造函数。

In this case, cbecomes the alias of carobj.

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

Using the above 2 scenarios, for your clarity I am summarizing them as:

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

  1. If a function is declared to take a parameter as value of a object, then the copy constructor of the object is called.

  2. If a function is declared to take a parameter as "pass by reference", the parameter becomes an alias of the object supplied by the caller. No need of a copy constructor!

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

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

Now the question is why pass by reference is required. If copy constructor accepts reference, the receiving variable become aliases of supplied object. Hence, no need of copy constructor (in this case, call to itself) to copy the value in caller supplied object to copy constructor's variable in argument list.

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

Otherwise, if copy constructor takes the caller supplied object as value, i.e. pass by value, then it needs the copy constructor of the given object; hence, to get the supplied object from caller into our function itself (in this case the copy constructor) we need to call the copy constructor, which is nothing but calling the same function during function declaration.

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

That's the reason for passing a reference to a copy constructor.

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

回答by anand tripathi

It is necessary to pass object as reference and not by value because if you pass it by value its copy is constructed using the copy constructor.This means the copy constructor would call itself to make copy.This process will go on until the compiler runs out of memory.

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

回答by Dalbir Singh

It is very essential to pass objects as reference. If an object is passed as value to the Copy Constructor then its copy constructor would call itself, to copy the actual parameter to the formal parameter. Thus an endless chain of call to the copy constructor will be initiated. This process would go on untill the system run out of memory.

将对象作为引用传递是非常必要的。如果对象作为值传递给复制构造函数,则其复制构造函数将调用自身,将实际参数复制到形式参数。因此,将启动对复制构造函数的无限调用链。这个过程会一直持续到系统内存不足。

Hence, in a copy constructor, the parameter should always be passed as reference.

因此,在复制构造函数中,参数应始终作为引用传递。

回答by ishaang

If its not passed by reference then it would pass by value. If the argument is passed by value, its copy constructor would call itself to copy the actual parameter to formal parameter. This process would go on until the system runs out of memory. So, we should pass it by reference , so that copy constructor does not get invoked.

如果它不是通过引用传递,那么它将通过值传递。如果参数是按值传递的,它的复制构造函数会调用自己将实参复制到形参。这个过程会一直持续到系统内存不足。所以,我们应该通过引用传递它,这样复制构造函数就不会被调用。