1

I've just write a class for complex numbers as you can see it's code below ;suppose A and B are Complex numbers , my problem is that when I write the code:

cout << A+B; // it gives me an error

But when I assign A+B to a instance of class Complex, say C , it works correctly . I mean:

Complex C=A+B << endl; cout << C; // works correctly

I'm really confused why I couldn't use A+B as a right operand for << operator . Any ideas How could I cout A+B directly?? thanks in advance for your help. Here's what I came up with so far :

   #include <iostream>
   using namespace std;

class Complex {
     private:
        double real;
        double image;
     public:

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

    int GetReal(){ return real;}
    int GetImage(){return image;}



    //overload complex + complex
    friend Complex operator+(const Complex &c1,const Complex &c2) ;
    //overload complex + double
    friend Complex operator+(const Complex &c,double Number) ;
    //overload double + complex
    friend Complex operator+(double Number,const Complex &c) ;

    //overload complex * complex
    friend Complex operator*(const Complex &c1, const Complex &c2);
    //overload complex * double
    friend Complex operator*(const Complex &c, double Number);
    //overload double * complex
    friend Complex operator*(double Number, const Complex &c);

    //overloading output operator
    friend ostream& operator<< (ostream &out, Complex &c);
 };
Complex operator+(const Complex &c1,const Complex &c2){
     return Complex(c1.real + c2.real,c1.image + c2.image);}

Complex operator+(const Complex &c,double Number){
     return Complex(c.real + Number , c.image);}

Complex operator+(double Number,const Complex &c){
     return Complex(Number + c.real,c.image);}

 //(a + bi) * (c + di) = ((ac-bd) + (ad+bc)i)
Complex operator*(const Complex &c1, const Complex &c2){
     return Complex(c1.real*c2.real-c1.image*c2.image,c1.real*c2.image+c1.image*c2.real);}

Complex operator*(const Complex &c, double Number){
     return Complex(c.real*Number,c.image*Number);}

Complex operator*(double Number, const Complex &c){
     return Complex(Number*c.real,Number*c.image);}

ostream& operator<< (ostream &out, Complex &c){
     if( c.image>0){

          out << c.real << "+ " <<
                c.image << "i";}
     else if (c.image==0){
          out<<c.real;
       }
     else { out<< c.real<<"- "<<
             c.image<< "i";}

     return out;}

int main(){

Complex A(1,2);
Complex B(3,4);

cout<<"A is: "<<A<<endl;
cout<<"B is: "<<B<<endl;
Complex c=A+B;
cout<<c<<endl;  //works correctly
cout<<A+B<<endl;  // gives an Error ?!


}
Soheil__K
  • 642
  • 1
  • 8
  • 17

2 Answers2

6

A+B is an rvalue because your operator+ (rightly) returns by value. You cannot bind a non-const lvalue reference to an rvalue. You need to change the operator to take a const reference:

friend ostream& operator<< (ostream& out, const Complex& c);
                                          ^^^^^
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
2

You need the parameter to be a const reference, not a mutable reference. I.e., change Complex& c in your definition and declaration of operator<< to const Complex& c, and it should work. The reason for this is that a temporary result (such as a + b) cannot be modified, whereas a named non-const variable can be.

Michael Aaron Safyan
  • 93,612
  • 16
  • 138
  • 200
  • Temporary class objects (such as `Complex` in this case) can be modified, you can even ref-qualify member functions that will only be called on rvalues with `void foo() &&;`. – user657267 May 08 '14 at 07:20
  • @user657267, you're right that a temporary can be modified as an rvalue reference. For simplicity of communication rather than strict technical correctness, though, I think it's more understandable to say that the object cannot be modified (i.e. cannot be implicitly converted to a non-const reference) than to say "a temporary cannot be an lvalue". – Michael Aaron Safyan May 11 '14 at 21:18