为什么复制构造函数的参数必须通过引用传递?
因为传值会调用复制构造函数 :)
除了传递引用之外的另一种方式是传递值。实际上,传递值是传递副本。需要使用拷贝构造函数来创建一个副本。
如果您必须在调用拷贝构造函数之前创建副本,这将是一个难题。
(我认为编译器会发生无限递归,因此您实际上永远不会得到这样的程序。)
除了理性原因外,在 §12.8/3 中标准中禁止这样做:
如果类X的第一个参数是类型(可以选择进行cv限定),并且没有其他参数,或者所有其他参数都具有默认参数,则类X的构造函数声明未定义。
如果按值传递它,那么这将是无限递归的
car carobj;
f(carobj);
即将carobj
复制到c
。carobj
复制到函数f
中的参数c
。为了实现复制,会调用复制构造函数。f
,换句话说,函数f
声明为按值传递。f
采用引用传递,则其声明如下:
int f(car &c);
在这种情况下,carobj
作为参数调用函数f
就不需要复制构造函数。c
成为carobj
的别名。这就是传递引用给复制构造函数的原因。
在IT技术中,传递对象时需要以引用方式而不是值的方式传递,因为如果您以值的方式传递,它的副本将使用复制构造函数进行构造。这意味着复制构造函数会调用自身来进行复制。这个过程将一直进行下去,直到编译器耗尽内存。
所有答案都是正确的,但我想知道是否有任何东西能够对像我这样通过示例学习的初学者有所帮助。因此,这里是一个例子。
以这段代码为例:
#include<iostream>
#include<cstring>
using namespace std;
class String
{
private:
char *s;
int size;
public:
String(const char *str)
{
size=strlen(str);
s=new char[size+1];
strcpy(s,str);
}
~String()
{
delete[] s;
}
String(const String& old_str)
{
size=old_str.size;
s=new char[size+1];
strcpy(s,old_str.s);
}
void print()
{
cout<<s<<endl;
}
void change(const char *str)
{
delete [] s;
size=strlen(str);
s=new char[size+1];
strcpy(s,str);
}
};
int main()
{
String str1("Hello World");
String str2=str1;
str1.print();
str2.print();
str2.change("Namaste");
str1.print();
str2.print();
return 0;
}
这是拷贝构造函数:
String(const String& old_str)
{
size=old_str.size;
s=new char[size+1];
strcpy(s,old_str.s);
}
假设我们不通过引用传递参数。即:
String(const String old_str)
{
size=old_str.size;
s=new char[size+1];
strcpy(s,old_str.s);
}
看一下 int main() 函数。
String str2=str1
再次查看拷贝构造函数(不使用引用)。
String(const String old_str)
这意味着:
String old_str=str1
这基本上是在main()函数中写的相同的东西。因此,它再次调用了复制构造函数。在C++中调用复制构造函数的规则是当你有这样的情况:
ABC a;
ABC b=a;
希望这有帮助。
object o(other_object)
来自行复制一个对象时,通常会实现一个复制构造函数。但是,这只有在object
具有按值或按引用接受另一个object
的构造函数时才起作用。您已经知道为什么按值传递不起作用了,所以唯一的方法是通过引用或常量引用进行传递。如果您的“复制构造函数”将采用指向object
的指针,则编译器的代码必须是object o(&other_object)
。因此,本质上您编写的构造函数满足编译器和用户的期望。 - wilhelmtell