-1
#include <iostream>
using namespace std;

class Complex {
private:
    int real;
    int img;

public:
    //Constructor
    Complex(int a=0, int b=0);
    //Copy Constructor
    Complex (Complex &c); //Here why do I have to use reference why can't I use call by value like in 
                          //function add
    //function
    Complex add(Complex c);
    void display();
};

Complex::Complex(int a, int b) {
    real = a;
    img = b;
}

Complex::Complex (Complex &c) {
    real = c.real;
    img = c.img;
}

Complex Complex::add(Complex c) {
    Complex temp;
    temp.real = real + c.real;
    temp.img = img + c.img;
    return temp;
}

void Complex::display() {
    cout<<real<<" +i"<<img<<endl;
}

int main() {
    Complex c1(2,4), c2(3,5), c3(c1), c4;
    c4=c1.add(c2);
    c1.display();
    c2.display();
    c3.display();
    c4.display();
    return 0;
}

I couldn't understand the reason of using pass by reference there. If I try to use pass by value, I get an Compiler error message: error: invalid constructor; you probably meant Complex(const Complex&)

Priyansh
  • 41
  • 1
  • 6
  • 2
    A copy constructor should have a _const reference_ parameter. If the copy constructor took a pass-by-value as the parameter, it would then have to call the copy constructor to make the copy of the parameter, which would recurse until stack overflow. – Eljay Mar 20 '20 at 19:10

3 Answers3

1

Consider the constructor

Complex(Complex c);

How does that argument c get created?

It gets created from the argument passed in at the call site. But since it's a value, we get a copy which needs to be constructed.

But this will simply call the copy constructor, and that's the very thing you are trying to define. This would be infinite recursion, and doesn't make sense, and the compiler prevents you from doing that.

cigien
  • 57,834
  • 11
  • 73
  • 112
1

Well, let's say we do write the copy constructor like you say. So maybe we have the constructors

Complex(int a=0, int b=0) : real(a), imag(b) {}
Complex(Complex c);

Now, let's see how we use the copy constructor

Complex a(1,1); // the first constructor
Complex b(a);   // the copy constructor

So, you expect that the object named c in the copy constructor's parameter list is actually a in the calling code, right?

Wrong! When you pass by value, the source object is copied into the argument list object - which is a local variable in the context of the function you're calling.

Which means you can't call the copy constructor without first copying its argument by calling the copy constructor by first ... getting stuck in an infinite regression.

We don't always use function arguments like this, but you can always mutate a function's value arguments as normal local variables, without mutating the caller's original object. Unless, of course, you pass instead by (const) reference.

Useless
  • 64,155
  • 6
  • 88
  • 132
1

Because it causes infinite recursion. Let me explain.

Every time you pass an object by value, it gets copied. How exactly does it do this? With the copy constructor.

Now suppose you pass by value in a copy constructor:

Complex::Complex (Complex c) {
   //...
}

How is the value of c determined? Well, by copying it, of course. And to do that, we need to call the copy constructor...

So, in other words, we find ourselves in a situation where we need to call the copy constructor before we even execute the copy constructor! Thus, we really have no way of copying the data. Doing so would be infinite recursion and just crater.