I'm learning C++ and I created two simple hello-world applications. In both of them I use operator overload, but here is the problem. On the first one, I can provide two arguments to overload operator, and it's fine.
Header:
enum Element {a,b,c,d,e};
Element operator + (Element x, Element y);
//more overloads for -, *, / here
Source:
Element operator + (Element x, Element y) {
return ArrayOfElements[x][y];
}
But in my second app (simple complex number calculator) - this method didn't work. After googling and figuring out why, I end up with this code:
Header:
struct Complex {
double Re;
double Im;
Complex (double R, double I) : Re(R), Im(I) { }
Complex operator + (Complex &Number);
//more overloads
};
Source:
Complex Complex::operator + (Complex &Number)
{
Complex tmp = Complex(0, 0);
tmp.Re = Re + Number.Re;
tmp.Im = Im + Number.Im;
return tmp;
}
It's working now, but I want to know, why in the first piece of code I was allowed to put two arguments in operator
overloading, but with the second one I was given the following error?
complex.cpp:5:51: error: 'Complex Complex::operator+(Complex, Complex)' must take either zero or one argument
It's the same whenever I use classes or not. I've been seeking through many docs and the second way seem to be more correct. Maybe it's because of different argument types?
Both sources compiled with -Wall -pedantic
parameters using g++
, both are using the same libraries.
Overloading Binary Operator: In binary operator overloading function, there should be one argument to be passed. It is overloading of an operator operating on two operands.
Two operators = and & are already overloaded by default in C++. For example, to copy objects of the same class, we can directly use the = operator. We do not need to create an operator function. Operator overloading cannot change the precedence and associativity of operators.
When unary operators are overloaded through a member function, they do not take any explicit arguments. But when overloaded by a friend function, they take one argument. When binary operators are overloaded through a member function they take one explicit argument.
sizeof cannot be overloaded because built-in operations, such as incrementing a pointer into an array implicitly depends on it.
Suppose you have a class like this:
class Element {
public:
Element(int value) : value(value) {}
int getValue() const { return value; }
private:
int value;
};
There are four ways to define a binary operator such as +
.
As a free function with access to only the public
members of the class:
// Left operand is 'a'; right is 'b'.
Element operator+(const Element& a, const Element& b) {
return Element(a.getValue() + b.getValue());
}
e1 + e2 == operator+(e1, e2)
As a member function, with access to all members of the class:
class Element {
public:
// Left operand is 'this'; right is 'other'.
Element operator+(const Element& other) const {
return Element(value + other.value);
}
// ...
};
e1 + e2 == e1.operator+(e2)
As a friend
function, with access to all members of the class:
class Element {
public:
// Left operand is 'a'; right is 'b'.
friend Element operator+(const Element& a, const Element& b) {
return a.value + b.value;
}
// ...
};
e1 + e2 == operator+(e1, e2)
As a friend
function defined outside the class body—identical in behaviour to #3:
class Element {
public:
friend Element operator+(const Element&, const Element&);
// ...
};
Element operator+(const Element& a, const Element& b) {
return a.value + b.value;
}
e1 + e2 == operator+(e1, e2)
If you prefer that operator+
takes both operands as explicit arguments, it must be defined as a free (i.e. non-member) function:
class Complex {
friend Complex operator+(const Complex& lhs, const Complex& rhs);
}
Complex operator+(const Complex& lhs, const Complex& rhs) {
...
}
You have to use this form if the left operand is of a primitive type, or of a class that you don't control (and thus can't add a member function to).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With