1

为什么我们通过引用传递一个类的对象。当我删除与号 (&) 时,我收到以下错误。

"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;
}
4

4 回答 4

5

想象一下,如果你不这样做会发生什么:

1) 参数现在按值传递给复制构造函数

2)为了通过值传递它调用复制构造函数

3) 转到 1

于 2014-03-12T10:42:43.810 回答
5

在 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

于 2014-03-12T10:45:07.483 回答
2

在 C++ 中,将变量传递给函数/方法有三种方法:按值传递、按地址传递和按引用传递(实际上是在漂亮的包装器中按地址传递)。按地址传递和按引用传递是最简单的,因为传递给底层函数/方法的实际上是您传递的对象所在的内存地址。但是,为了按值传递,必须制作源对象的副本。这就是复制构造函数的工作。

为了让复制构造函数接受 A 的实例,您必须能够制作 A 的副本,这需要复制构造函数,这是一个递归要求。

于 2014-03-12T10:42:57.290 回答
1

当您按值传递对象时,它会调用复制构造函数。因此,如果您的复制构造函数需要在实例运行之前对其进行复制,那么它怎么能运行呢?

& 号告诉它通过引用传递它,所以没有复制。

于 2014-03-12T10:41:48.860 回答