为什么我们通过引用传递类的对象。当我删除&符号(&)时出现以下错误。
"Copy constructor of class A may not have parameter of type A"
这是什么意思?可能是编译器没有考虑给定一个复制构造函数并使用默认值。如果是这种情况,为什么要调用默认值。简而言之,为什么我们使用&符号会发生什么?如果我们不这样做。
class A
{
public:
A()
{
}
A(A& tmp)
{
id = 2*tmp.id;
}
public:
int id;
};
int main()
{
A obj;
obj.id = 10;
A obj1(obj);
cout << obj1.id;
}
答案 0 :(得分:5)
想象一下,如果你不这样做会发生什么:
1)现在,该参数按值传递给复制构造函数
2)为了按值传递它,它会调用复制构造函数
3)转到1
答案 1 :(得分:4)
在C ++中,函数可以通过值或引用获取其参数。如果他们按值获取参数,则该值必须是可复制的。如果复制构造函数可以按值获取其参数,那么您需要一个复制构造函数来传递它的参数,这将导致无限循环。
考虑:
class MyInt
{
int m;
public:
MyInt(int i)
{
m = i;
}
MyInt(MyInt j)
{
j.m++;
m = j.m;
}
};
MyInt a(1);
MyInt b(a);
编译器如何使这项工作?如果它使用默认的复制构造函数,那为什么它需要调用我的构造函数?如果它使用我的构造函数,它如何阻止a.m
递增(这显然是错误的,a
在通过值传递时不应该更改),因为没有代码给构造函数自己的副本?
答案 2 :(得分:1)
它是按值传递对象时调用的复制构造函数。 因此,如果你的拷贝构造函数要求在它运行之前复制实例,它怎么能运行呢?
&符号告诉它通过引用传递它,因此不会复制。
答案 3 :(得分:1)
有三种方法可以将变量传递给C ++中的函数/方法:按值传递,按地址传递,按引用传递(实际上是通过漂亮的包装器中的地址传递)。传递地址和按引用传递是最简单的,因为传递给底层函数/方法的实际上是传递对象所在的内存地址。但是,为了传递值,必须创建源对象的副本。这是复制构造函数的工作。
为了让复制构造函数接受A的实例,您必须能够复制A,这需要复制构造函数,递归需求。