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 argume
Since + is a binary operator, if you overload it inside a struct/class, you can only provide one more operand, the reason is that the first operand is implicitly the calling object. That is why in the first case, you have two parameters since it is outside scope of your class/struct, while in the second case, it was overloaded as member function.
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 overloaded function is a member function to the class, the we pass only one argument, and there is one hidden parameter (this pointer) that points to other object required to perform binary operation like '+'. this pointer points to one of the operands and calls the overloaded function; while other operand is passed as an argument. Example:
class ExampleClass
{
public:
int x;
//a this pointer will be passed to this function
ExampleClass& operator+(const ExampleClass& o){ return x+o.x; }
};
ExampleClass obj1, obj2, obj;
obj = obj1 + obj2; //the overloaded function is called as obj1.operator+(obj2) internally
//this pointer is passed to the function
When the overloaded function is not a member function (either a free function or a friend function), then we don't have the this pointer provided to the overloaded function. In this case, the compiler expects two arguments to the function which are used as operands.
class ExampleClass
{
public:
int x;
//this pointer will not be passed to this function
friend ExampleClass& operator+(const ExampleClass& o1, const ExampleClass& o2){ return o1.x+o2.x; }
};
obj = obj1 + obj2; //the overloaded function is called as operator+(obj1, obj2) internally
e1 + e2 == e1.operator+(e2) this means e1 is a object and operator+ is a member and e2 is as a variable .basicaly oops permits us to do just write e1 + e2 compiler automatically understand as a e1.operator+(e1)