-4

I have written the following code to do operator overloading for basic operations on complex numbers, here I have put only the addition. When running it, I get trillions of errors. I have seen several other posts regarding this but I have just started learning C++. I would be most grateful if you could point out in general the mistakes I am making in operator overloading (It is not about debugging, but I would appreciate some general explanations as I have seen examples of the same operator overloading but could not understand several features such as the use of pointer and const). Thanks in advance.

#include<iostream>

using namespace std;

class Complex 
{
private: 
    double real;
    double imaginary;

public:
    Complex(double r, double i);    
    // addition
    Complex operator+(Complex c1, Complex c2);      
};

Complex::Complex(double r, double i)
{
    real = r;
    imaginary = i;
}

Complex Complex::operator+(Complex c1, Complex c2) 
{
    Complex result;
    result.r = c1.r + c2.r;
    result.i = c1.i + c2.i;
    return result;
}

ostream ostream::operator<<(ostream out, Complex number)
{
    out << number.r << "+" << number.i << endl;
}

int main() {
    Complex y, z;
    Complex sum;
    y = Complex(2, 4);
    z = Complex(3, 0);

    cout << "y is: " << y << endl;
    cout << "z is: " << z << endl;

    sum = y+z;

    cout << "The sum (y+z) is: " << sum << endl;

    return 0;
}
David G
  • 94,763
  • 41
  • 167
  • 253
Lucia
  • 901
  • 1
  • 11
  • 16
  • 3
    If you want us to comment on why you are receiving specific errors, you should post verbatim what those errors are. – Cory Kramer Dec 15 '14 at 20:44
  • Lots of problems. Read the thread on operator overloading. You also need a default-constructor. – David G Dec 15 '14 at 20:57

1 Answers1

0

There are tons of errors here, from incorrect attempts to overload operators to using data members by the wrong name. I'll step through what I see.


When defining the binary operator+ as a member function it only takes one argument, which is the right-hand argument to + (the left-hand is implicitly *this).

Also your operators use the nonexistent fields r and i -- you probably meant real and imaginary.

class Complex
{
    // ...

public:
    // Wrong, will cause compile-time errors:
    // Complex operator+(Complex c1, Complex c2);  

    // Right:
    Complex operator+(Complex c);
};

Complex Complex::operator+(Complex c) 
{
    Complex result;
    result.real = real + c.real;
    result.imaginary = imaginary + c.imaginary;
    return result;
}

Alternatively you can define the operator as a free function instead of as a member of the class, but you'd have to make it a friend of the class since it accesses private members:

class Complex
{
    // ...

    friend Complex operator+(Complex, Complex);
};

Complex operator+(Complex c1, Complex c2) 
{
    Complex result;
    result.real = c1.real + c2.real;
    result.imaginary = c1.imaginary + c2.imaginary;
    return result;
}

Similarly, your operator<< overload for std::ostream should be a free function, and needs to be fixed to use real and imaginary. However, since these members are private to Complex, this will fail unless you make this operator a friend of Complex. Since ostream is an abstract type you can't accept or return instances by value, you need to use references. Further you don't actually return anything.

class Complex
{
    // ...

    friend ostream & operator<<(ostream &, Complex);
};

ostream & operator<<(ostream & out, Complex number)
{
    out << number.real << "+" << number.imaginary << endl;
    return out;
}

Your Complex class is missing a default constructor, so you can't declare variables like Complex c; because this requires the existence of the default constructor:

class Complex
{
    // ...

public:
    Complex();
};

Complex::Complex() : real(0), imaginary(0) { }
cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • In the `operator<<` overload you should `return out` – w.b Dec 15 '14 at 21:02
  • @w.b Thanks, fixed. I also changed the operator to return the ostream by reference, since returning an abstract type by value is nonsensical. – cdhowie Dec 15 '14 at 21:03
  • The parameters of the free `operator+()` function should take lvalue-references to const. – David G Dec 15 '14 at 21:04
  • @0x499602D2 Good catch on the friendship. I thought about bringing up passing `Complex` objects by reference but decided against it because it's not technically an error, and the default copy-ctor will do the right thing. It's inefficient at worst. – cdhowie Dec 15 '14 at 21:06
  • btw `operator<<` should also take `ostream` parameter by reference – w.b Dec 15 '14 at 21:07
  • I see, thank you very much. I only now understand a lot of things that I was studying during this week. I was wondering about another thing. In the similar codes, I have seen the operator overloading with this syntax: `ComplexNumber add (const ComplexNumber &a, const ComplexNumber &b)` . How const and & affect the code? I read that const is a complex concept but the simplest meaning of it is that it keeps the variables constant throughout the program and & as in C should be the address-of operator. Butdon't understand how they would affect the program compared to the one I have tried to write – Lucia Dec 15 '14 at 21:07
  • @Homa I assume you mean `operator+` instead of `add`. And yes, you should accept by const reference. This allows you to accept a reference to an existing object rather than copying an object (this is very important if your object can hold a lot of data -- you don't want to copy that data every time you want another function to inspect it, you'd rather just give them a reference to existing data). `const` in this context means that while the function accepts a reference to an existing object, it is promising that it will not modify that object through the reference. – cdhowie Dec 15 '14 at 22:27
  • @Homa It's the difference between someone saying "give me a copy of your SD card so I can do something with the data" (pass by value) and "let me borrow your SD card for a sec so I can do something with the data, but I promise I won't change anything on it" (pass by const reference). – cdhowie Dec 15 '14 at 22:28
  • Really great explanations, thanks a lot. I am sorry for my full of mistake code, I have been studying a lot but I am a biology student and have little background, though wanna so much learn programming concepts so I needed someone for once at least explain these things. Thanks a lot again. – Lucia Dec 15 '14 at 22:56
  • Shouldn't the addition operator overloading be also like this: `friend Complex operator+(const Complex& c1, const Complex& c2)` ? because it contains parameters (c1 and c2) of type class. – Lucia Dec 16 '14 at 10:58
  • @Homa That's another good place to use references, yes. – cdhowie Dec 16 '14 at 15:49