Reputation: 135
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
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
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
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