L14 - Operator overloading
overloading the == operator: operator==
another common operator we can overload is the == operator. We can use this to compare equality, but technically we can do whatever we want in the operator== function. But let's just say that we want to compare for two objects for equality. We must then:
- Feed the RHS object into the
operator==function through pass-by-value or pass-by-reference - Compare each value in the two objects; if they are not the same, return a
falseboolean - Return a copy of a boolean instead of a reference to one
continued example from L13: operator+ and operator==
#include <iostream>
using namespace std;
class Complex {
private:
double real, img;
public:
Complex() { // first constructor
real = 0.0;
img = 0.0;
}
Complex (double r, double i) { // second constructor
real = r;
img = i;
}
Complex operator+(const Complex &rhs) const {
// as good practice, we should use a reference
// instead of a pass by value to save on memory
// const Complex &rhs prevents changes to rhs
// const {} prevents changes to object you invoke function on
// we do this because we don't want to change x and y; we just want to
// create a new object that is the sum
Complex temp;
temp.real = real + rhs.real;
temp.img = img + rhs.img;
return temp; // returning a COPY of temp (by value)
// we can't return a reference here because the object will no longer exist
// in the memory once this function goes out of scope
}
bool operator==(const Complex& rhs) {
// we don't have to pass the lhs because we are invoking the function
// on the lhs object
if (real == rhs.real && img == rhs.img) {
return true;
} else {
return false;
}
// or we could just return (reall==rhs.real)&&(img==rhs.img);
}
}
int main(void) {
Complex x(3,4); // calls second constructor
Complex y(5,6); // calls second constructor
Complex z; // calls first constructor
z = (x + y);
if (x == y) {
// we can only do this because we defined our own operator== above
}
}
operator+ replaces the + operator in the main function
i.e., (x+y) calls .operator+() automatically. However, this depends on the data types passed through. If the data types differ from what we define, we need to define a new function in the class.
default operator=
By default, the compiler will give a default operator= function to all classes if not implemented. This sets all data members of LHS to RHS.
e.g.
z=q;is the same asz.operator=(q);, which sets all data members on LHS to RHS.
What does this look like?
#include <iostream>
using namespace std;
class Complex {
private:
double real, img;
public:
Complex() { // first constructor
real = 0.0;
img = 0.0;
}
Complex (double r, double i) { // second constructor
real = r;
img = i;
}
Complex& operator=(const Complex& rhs);
// we return by reference here to obey the C++ standard
// this returns the original object on which we invoked the function
// but we do NOT add a const because that would prevent us from making
// any changes to the object
}
Complex::operator=(const Complex& rhs) {
real = rhs.real;
img = rhs.img;
return *this; // returns the object that the function is called on
}
int main(void) {
Complex x(3,4); // calls second constructor
Complex y(5,6); // calls second constructor
Complex z; // calls first constructor
z = (y = x);
// same as calling z.operator(y.operator=(x));
}
Notes:
- In the case of
operator=, we do return a reference, as we are modifying the LHS object. Thus, we define theoperator=function with return type that is a reference to the object it is being called on. - Because we are actually modifying the value of the LHS, i.e. the value that the reference is referring to, we do not use a
constin the function definition. - However, we still prefer to use a
constfor the pass-by-value RHS because we do not wish to overwrite the value of the RHS.
So, the function header looks like this:
Complex& operator=(const Complex& rhs)
In C++, we need to return the object on the RHS from operator= in a chained assignment operator.
chained assignments
In C/C++, doing z = y = x:
- first calls
y = x, i..ey.operator=(x) - then, calls
z = y, i.e.z.operator(y)
In essence, C/C++ read from right to left with chained assignments.

this as a return value in a class function
this is a pointer to the object on which the class function is invoked on.
*thisreturns the object itself, sothishas data type ofObject*this->realreturns the value of a variable in the object
So, we can usethisto return the object itself from the function
e.g. in
z = operator=(y),thispoints tozin theoperator=function