how to overload + and += operators as non-member functions? - c++

I'm currently trying to refresh and improve my C++ skills and I'm reading a few books in parallel depending on the subject I need to dig into.
I'm currently spending time on The C++ Programming Language from Stroustrup. At page 61/62, there's an example of class for Complex numbers. It overloads a number of operators like += and -=. At the same time, it says that "Many useful operations do not require direct access to the representation of complex, so they can be defined separately from the class definition".
Now, when I try the following code:
#pragma once
#include <iostream>
class Complex
{
private:
double re, im;
public:
Complex(double r, double i): re{r}, im{i} {}
Complex(double r): re{r}, im{0} {}
Complex(): re{0}, im{0} {}
double real() const { return re; }
void real(double d) { re = d; };
double imag() const { return im; }
void imag(double d) { im = d; }
void print();
Complex& operator+= (Complex z) { re += z.re, im += z.im; return *this; }
Complex& operator-= (Complex z) { re -= z.re, im -= z.im; return *this; }
};
Complex operator+ (Complex a, Complex b) { return a += b; }
I get a link error: class Complex_cdecl operator+(class Complex, class Complex) already defined in Complex.obj
One or more multiply defined symbols found.
So, I suppose the code presented in the book here is only partial. I can't figure out though what's the right way to overload both + and +=. Is the book wrong here or obsolete?
Thanks for your help.

In your example the operator + should either be made inline so that the linker knows that multiple obj files can contain the same function definition.
inline Complex operator+ (Complex a, Complex b) { return a += b; }
Or the header file should contain only the declaration
Complex operator+ (Complex a, Complex b);
and exactly one cpp file should contain the definition
Complex operator+ (Complex a, Complex b) { return a += b; }

Related

Question about class complex in the page 61 of book c++ programming language

class complex {
double re, im; // representation: two doubles
public:
complex(double r, double i) :re{r}, im{i} {} // construct complex from two scalars
complex(double r) :re{r}, im{0} {} // construct complex from one scalar
complex() :re{0}, im{0} {} // default complex: {0,0}
double real() const { return re; }
void real(double d) { re=d; }
double imag() const { return im; }
void imag(double d) { im=d; }
complex& operator+=(complex z) { re+=z.re , im+=z.im; return ∗this; } // add to re and im
// and return the result
complex& operator−=(complex z) { re−=z.re , im−=z.im; return ∗this; }
complex& operator∗=(complex); // defined out-of-class somewhere
complex& operator/=(complex); // defined out-of-class somewhere
};
In my opinion, the format of function declaration should look like that, (return type) name (argument){}. In this case,
complex& operator+=(complex z) { re+=z.re , im+=z.im; return ∗this; }
The complex& is the return type and operation+ is the function name, but why it is followed by a "="?
With operator + you can do something like:
c = a + b;
whti operator += is used to add some data and store it in the first summand:
a += b;
operator+= is itself a function.
The following expression
com_num+=com_other;
is equivalent to the call.
com_num.operator+=(com_other);

Why does the textbook uses an initializer list as the return value of operator-(complex a)?

I am reading a textbook (of Bjarne Stroustrup) definition of class complex
class complex {
double re, im; // representation: two doubles
public:
complex(double r, double i) :re{r}, im{i} {} // construct complex from two scalars
complex(double r) :re{r}, im{0} {} // construct complex from one scalar
complex() :re{0}, im{0} {} // default complex: {0,0}
double real() const { return re; }
void ral(double d) { re = d; }
double imag() const { return im; }
void imag(double d) { im = d; }
complex& operator+=(complex z) { re+=z.re, im+=z.im; return *this; } // add to re and im
// and return the result
complex& operator-=(complex z) { re-=z.re, im-=z.im; return *this; }
complex& operator*=(complex); // defined out-of-class somewhere
complex& operator/=(complex); // defined out-of-class somewhere
};
The book also defines operations of complex:
complex operator+(complex a, complex b) { return a+=b; }
complex operator-(complex a, complex b) { return a-=b; }
complex operator-(complex a) { return {-a.real(), -a.imag()}; } // unary minus
complex operator*(complex a, complex b) { return a*=b; }
complex operator/(complex a, complex b) { return a/=b; }
I do not understand the third line above, which deals with unary minus. Why does it make sense to use an initializer list as the return value of operator-(complex a);?
You have to have
return {-a.real(), -a.imag()};
because you want to return a complex that is created from those two values. If you tried using
return -a.real(), -a.imag();
instead then you would return a complex that was created from just -a.imag() since the comma operator only returns the last value. Essentially, the code is exactly the same as
return -a.imag();
To make it more explicit, the author could have written
return complex{-a.real(), -a.imag()};
//or
return complex(-a.real(), -a.imag());
but that really isn't needed since the return value is always converted to the return type and with initializer lists, they are used like you had typed return_type{ initializers }.
Without the initializer list you have to write
complex operator-( complex a ) { return complex( -a.real(), -a.imag() ); }
With the initializer list the definition of the operator looks simpler.
In any case the compiler selects the constructor
complex( double, double );
Take into account that in general the function should be declared like
complex operator-( const complex &a ) { return { -a.real(), -a.imag() }; }
The return type of that function is a complex object, so those parameters in the intitializer list are inferred as parameters to complex constructor and a new object is returned.

Overloading operators outside of the class

So, i have a simple class:
class complex{
private:
double a,b;
public:
void setA(double a){ this->a=a; }
void setB(double b){ this->b=b; }
double getA(){ return a; }
double getB(){ return b; }
friend complex operator+(const complex&, const complex&);
};
And i have the actual overloaded operator here:
complex operator+(const complex& x, const complex& y){
complex c;
c.a=x.a+y.a;
c.b=x.b+y.b;
return c;
}
I must have the operator overloaded outside of the function. In order to have access to private variables (those also HAVE to be private) I befriended the class with the function. I don't know if that's correct way to do such things, but at least it works.
I want to be able to add an integer to both members. In main():
complex a;
a.setA(2);
a.setB(3);
a+5;
Would result in having a.a=7 and a.b=8. Such overload inside the class is quite easy to make (Again, don't know if that's good solution, if not please correct me):
complex operator+(int x){
this->a+=x;
this->b+=x;
}
But I have no idea how to make it outside of the class because i can't use "this" pointer.
The usual approach to this sort of problem is to have member functions that define the reflexive version of arithmetic operators and free functions that define the non-reflexive version, implemented with the reflexive version. No friend declarations needed. For example:
class complex {
public:
complex& operator+=(const complex& rhs) {
x += rhs.x;
y += rhs.y;
return *this;
}
private:
double x, y;
};
complex operator+(const complex& lhs, const complex& rhs) {
complex result = lhs;
result += rhs;
return result;
}
Having a+5 change the value of a is unusual, but if that's really wha you want, make operator+(int) a member. However, users would typically expect that a+5 would leave a unchanged, and that a += 5 would modify a.

operator overloading and non-member functions c++

I have written a class for complex numbers in which I have overloaded the operator + and everything works fine, however I need to implement this as a non-member function and I am not sure how, or why there is a benefit of doing so.
Here is my code .h:
class Complex
{
private:
double a;
double b;
public:
Complex();
Complex(double aGiven);
Complex(double aGiven, double bGiven);
double aGetValue();
double bGetValue();
double operator[](bool getB);
Complex add(Complex &secondRational);
Complex operator+(Complex &secondRational);
}
.cpp:
Complex Complex::add(Complex &secondRational)
{
double c = secondRational.aGetValue();
double d = secondRational.bGetValue();
double anew = a+c;
double bnew = b+d;
return Complex(anew,bnew);
}
Complex Complex::operator+(Complex &secondRational)
{
return add(secondRational);
}
Any help on how to make these as non-member functions will be greatly appreciated!
Here is the addition operator outside of the class:
Complex operator+(const Complex& lhs, const Complex& rhs) {
//implement the math to add the two
return Complex(lhs.aGetValue() + rhs.aGetValue(),
lhs.bGetValue() + rhs.bGetValue());
}
Of course you will need to declare aGetValue() and bGetValue() as const:
double aGetValue() const {return a;}
double bGetValue() const {return b;}
The usual approach to arithmetic operations is to define the reflexive versions of the operators as members and the pure versions as non-members, implementing them with the reflexive versions:
class complex {
public:
const complex& operator+=(const complex& rhs) {
real += rhs.real;
imag += rhs.imag;
return *this;
}
};
complex operator+(const complex& lhs, const complex& rhs) {
complex res(lhs);
res += rhs;
return res;
}
How is explained above by pippin1289.
Why is explained below:
Imagine one need to use object of class as
Complex c3 = 5 + c1;// for c3 object c1's real part (a) added with 5
As C++ preserve order of operand. Compiler resolve above addition call as
5.operator+ (const Complex & other);// which is not possible
Hence, overload it via free function.
Your class is exposing necessary information via public interface such as aGetValue() and bGetValue.
Hence, this free overloaded + operator function need not be friend of class.
Additionally, Prefer non friend non member function over member function as it helps reduce degree of encapsulation.
This is explained here ==> http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197?pgno=1
You can declare a friend to your Complex class
class Complex {
// blah....
friend Complex operator+(Complex const& a, Complex const & b);
};
The overloaded operator can access the private members of Complex.

How do I most efficiently return multiple values from an overloaded operator? (C++)

I have a class "complex" that contains a Real and an Imaginary value. I'm trying to overload the + operator so I can add real to real and imaginary to imaginary, but I'm banging my head against a wall here.
In the function, I can get the values easy. Returning them however, is a bitch.
My plan is to overload the '=' operator, too, so I can go
complex a, b, c;
(set a and b)
c = a + b;
then have a+b return a complex, then have complex c equal the complex returned by a+b
Any opinion on whether that's a viable path?
Any opinion on whether it can be done easier?
Return them as a complex! e.g.
const complex operator+(const complex &a, const complex &b)
{
return complex(a.re + b.re, a.im + b.im);
}
You shouldn't need to overload operator=; the compiler will generate one for you that does an element-by-element copy, which will probably suffice for a complex class.
I'm not sure I understand the problem. Do you have a complex class?
struct complex
{
complex(float real, float imag) :
real(real), imag(imag)
{}
// first make the mutating version
complex& operator+=(const complex& rhs)
{
real += rhs.real;
imag += rhs.imag;
return *this;
}
float real, imag;
};
// then use that for the non-mutating version
complex operator+(complex lhs, const complex& rhs)
{
lhs += rhs;
return lhs;
}
This is, of course, just an exercise; we have std::complex.
What's wrong with overloading the + operator:
complex operator+(const complex& a, const complex& b) const {
return complex(a.real + b.real, a.imag + b.imag);
}
And the operator=() similarly? (but the compiler give you this by default)
complex& operator=(const complex& a) {
real = a.real;
imag = a.imag;
return *this;
}
It is viable but there is already complex class in standard library. Reuse it or at least have a look how the operator overloading is done there.