Bozidar Vulicevic
Bozidar Vulicevic

Reputation: 135

An inquiry on operator overloading, example simple code on complex numbers, adding

    class Complex
{
private:
    float re;
    float im;
public:
    Complex(float r = 0.0, float i = 0.0) : re(r), im(i){}
    friend Complex operator+(Complex c1, Complex c2);
};

Complex operator+(Complex c1, Complex c2)
{
     return Complex(c1.re + c2.re, c1.im + c2.im);
}

int main()
{
    Complex c1(1,2);
    Complex c2(1,2);
    Complex c3;
    c3 = 1.0 + c2;

}

It is unclear to me why this works because, it seems that the float 1.0 is one argument in the operator and c2 is the other. Now I'm told that this is ok since the constructor is called, is this valid? And how do we know, that 1.0 is assigned to r and not i ??

Now the following is incorrect, and I ask why?

class Complex
{
    private:
        float re;
        float im;
    public:
        Complex(float r = 0.0, float i = 0.0) : re(r), im(i){}
        Complex operator+(Complex c1);
};

 Complex Complex::operator+(Complex c1)
{
    return Complex(this->re + c1.re, this->im + c1.im);
}

int main()
{
    Complex c1(1,2);
    Complex c2(1,2);
    Complex c3;
    c3 = 1.0 + c2;

}

This does not work, is it because 1.0 isn't an object of complex, and why isn't the constructor initialized here to make an object with re=1.0, im =0.0? As assumed in the first part of the question?

 error: no match for 'operator+' in '1.0e+0 + c2'|

Upvotes: 0

Views: 62

Answers (3)

user1138939
user1138939

Reputation:

Thanks for sharing question,

For first part I was debugging code and found that for point c3 = 1.0 + c2; C++ creates object of Complex (as expected) but with parameters (1.0 and 0). as shown below from debug info i have pasted below. Its similar to creating temporary Complex variable with call to default constructors and paramters passed as 1.0 and 0. aka Complex(1,0) Hence it works fine.

Breakpoint 1, main () at probl.cpp:24

24 c3 = 1.0 + c2;

(gdb) s

Complex::Complex (this=0x23cc68, r=1, i=0) at probl.cpp:10

10 Complex(float r = 0.0, float i = 0.0) : re(r), im(i){}

As others suggested above in the second part "+" operator is part of Complex class and hence c3 = 1.0 + c2; will call only + operator if 1.0 was converted to proper complex class instance. Hence it gave compilation error. To resolve you can change code to

c3 = Complex(1.0) + c2;

Here temporary object of complex class is created with default value of re=1 and im =0 and then operator + is called to this temporary object. Hope this helps.

Upvotes: 1

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122298

In the first case, the constructor is called, because

Complex(float r = 0.0, float i = 0.0) : re(r), im(i){}

works like a conversion, when the second parameter is not passed. Thus any float can be converted to an Complex.

In the second case, if the operator is a member function:

Complex Complex::operator+(Complex c1)

it has to be called on an object of type Complex. However, when you write:

c3 = 1.0 + c2;

the + operator of float would be called with c2 as parameter ("would", because there is no such operator). If instead you write:

c3 = c2 + 1.0;

it should work, because now the + operator of c2 is called. It expects a Complex as parameter, 1.0 can be converted, so this would work.

Upvotes: 1

R Sahu
R Sahu

Reputation: 206577

When you implement operator+ as a member function, the LHS of the operator must be an object of type Complex.

When you implement operator+ as a non-member function, the LHS of the operator can be anything as long as there is a way to construct be an object of type Complex from it using implicit conversion.

That's why the non-member function version works while the member function version does not.

Upvotes: 2

Related Questions