Lesson 7 | Unary and binary operator overloading |
Objective | Difference between overloading Unary and Binary Operators |
Overloading Unary and Binary Operators as Non-Static Member Functions in C++
In C++, operator overloading allows custom behavior for operators when applied to user-defined types. When overloading as non-static member functions, the operator function becomes a member of the class and has direct access to the class's private members.
1. Unary Operator Overloading
Unary operators operate on a single operand (e.g., `+`, `-`, `++`, `--`, `!`, `~`).
Syntax for Overloading a Unary Operator
ReturnType operatorOp();
- No parameters are required since the operand is the calling object (
this
).
- Returns a modified object (by value or reference).
Example: Overloading Unary `-` Operator
#include <iostream>
using namespace std;
class Number {
private:
int value;
public:
// Constructor
Number(int v) : value(v) {}
// Overloading unary minus (-) operator as a member function
Number operator-() {
return Number(-value); // Negating value
}
// Display function
void display() const {
cout << "Value: " << value << endl;
}
};
int main() {
Number num1(10);
Number num2 = -num1; // Calls overloaded - operator
cout << "Original: ";
num1.display();
cout << "Negated: ";
num2.display();
return 0;
}
Explanation
operator-()
is a member function that negates value
.
- The overloaded operator is used as
-num1
, and it returns a new Number
object with the negated value.
2. Binary Operator Overloading
Binary operators work on two operands (e.g., `+`, `-`, `*`, `/`, `==`, `!=`, `>`, `<`).
Syntax for Overloading a Binary Operator
ReturnType operatorOp(const ClassName& obj);
- Takes one parameter (the second operand).
- The first operand is the calling object (
this
).
- Returns a result object.
Example: Overloading Binary `+` Operator
#include <iostream>
using namespace std;
class Point {
private:
int x, y;
public:
// Constructor
Point(int x = 0, int y = 0) : x(x), y(y) {}
// Overloading + operator
Point operator+(const Point& p) {
return Point(x + p.x, y + p.y);
}
// Display function
void display() const {
cout << "(" << x << ", " << y << ")" << endl;
}
};
int main() {
Point p1(3, 4), p2(1, 2);
Point p3 = p1 + p2; // Calls overloaded + operator
cout << "Point 1: ";
p1.display();
cout << "Point 2: ";
p2.display();
cout << "Sum: ";
p3.display();
return 0;
}
Explanation
operator+()
is a member function that adds the corresponding x
and y
values of two Point
objects.
- It allows
p1 + p2
, returning a new Point
object.
Key Points About Member Function Operator Overloading
Unary and binary operators can be overloaded as nonstatic member functions. Implicitly they are acting on a class value.
C++ Nonstatic Member Functions
Data members can be declared with the storage class modifier static
.
A data member that is declared static
is shared by all variables of that class and is stored uniquely in one place.
Since a static member is independent of any particular instance, it can be accessed in the form
static Storage Class
The static storage class instructs the compiler to keep a local variable in existence during the life-time of the program instead of creating and destroying it each time it enters and leaves scope.
Therefore, making local variables static allows them to maintain their values between function calls.
The static modifier may also be applied to global variables. When this is done, it causes that variable's scope to be restricted to the file in which it is declared.
In C++, when static is used on a class data member, it causes only one copy of that member to be shared by all objects of its class.
class name ::
identifier
Non-static members in C++
Nonstatic members are created for each instance of the class.
The
- assignment,
- function call,
- subscripting, and
- class pointer
operators can be overloaded only by nonstatic member functions.
Pointers to members (data and functions) work differently from other pointers. The syntax for declaring a pointer to a
nonstatic data member or a nonstatic member function requires a class name and scope operator before the asterisk. Pointers to members can never be cast to ordinary pointers, and vice versa. You cannot declare a reference to a member. A pointer to a
static member is an ordinary pointer, not a member pointer. The following are some simple examples of member pointers:
struct simple {
int data;
int func(int);
};
int simple::* p = &simple::data;
int (simple::*fp)(int) = &simple::func;
simple s;
s.*p = (s.*fp)(42);
Unary operators can be overloaded as ordinary functions that take a single argument of class or reference to class type.
Binary operators can be overloaded as ordinary functions that take one or both arguments of class or reference to class type. In the next several lessons, we will look closely at overloading both unary and binary operators. Take a look at the following unary operator overloading example, in this case the unary operators increment (++) and decrement (--):
//Increment and decrement overloading
class Inc {
private:
int count ;
public:
Inc() {
//Default constructor
count = 0 ;
}
Inc(int C) {
// Constructor with Argument
count = C ;
}
Inc operator ++ () {
// Operator Function Definition
return Inc(++count);
}
Inc operator -- () {
// Operator Function Definition
return Inc(--count);
}
void display(void) {
cout << count << endl ;
}
};
void main(void) {
Inc a, b(4), c, d, e(1), f(4);
cout <<"Before using the operator ++()\n";
cout << "a = ";
a.display();
cout << "b = ";
b.display();
++a;
b++;
cout << "After using the operator ++()\n";
cout << "a = ";
a.display();
cout << "b = ";
b.display();
c = ++a;
d = b++;
cout << "Result prefix (on a) and postfix (on b)\n";
cout << "c = ";
c.display();
cout << "d = ";
d.display();
cout << "Before using the operator --()\n";
cout << "e = ";
e.display();
cout << "f = ";
f.display();
--e;
f--;
cout << "After using the operator --()\n";
cout << "e = ";
e.display();
cout << "f = ";
f.display();
}

