Operator overloaidng enables custom types to define their own behavior for standard operators. The compiler recognizes overloaded operators through a consistent naming convention combining 'operator' with the symbol being overloaded.
Overloading Addition Operator
Both member functions and global functions can implement addition between classes and built-in types:
class NumberPair {
public:
NumberPair operator+(int value) {
NumberPair result;
result.x = this->x + value;
result.y = this->y + value;
return result;
}
int x;
int y;
};
void demoAddition() {
NumberPair pair;
pair.x = 10;
pair.y = 10;
NumberPair sum = pair + 10;
cout << sum.x << endl; // Outputs 20
}
Overloading Stream Insertion Operator
The stream insertion operater (<<) requires global function overloading to maintain proper operand order:
class DataPoint {
friend std::ostream& operator<<(std::ostream& os, const DataPoint& dp);
public:
DataPoint(int x, int y) : coordX(x), coordY(y) {}
private:
int coordX;
int coordY;
};
std::ostream& operator<<(std::ostream& os, const DataPoint& dp) {
os << dp.coordX << endl;
return os;
}
void demoStream() {
DataPoint point(10,20);
cout << point << endl;
}
When returning temporary objects, the parameter must be const-qualified too bind to rvalues:
struct Record {
int id;
string label;
};
ostream& operator<<(ostream& os, const Record& rec) {
os << rec.id << endl << rec.label << endl;
return os;
}
Record createRecord() {
Record r;
r.id = 10;
r.label = "Example";
return r;
}
Prefix and Postfix Increment Operators
class Counter {
public:
Counter& operator++() { // Prefix
++count;
return *this;
}
Counter operator++(int) { // Postfix
Counter temp = *this;
++count;
return temp;
}
private:
int count = 0;
};
Key differences:
- Prefix returns a reference (lvalue)
- Postfix returns by value (rvalue)
- The dummy int parameter distinguishes postfix
Function Call Operator (Functors)
class Printer {
public:
void operator()(const string& text) {
cout << text << endl;
}
};
class Adder {
public:
int operator()(int a, int b) {
return a + b;
}
};
void demoFunctors() {
Printer print;
print("Function object example");
Adder add;
int result = add(100, 200);
cout << result << endl;
// Anonymous temporary functor
cout << Adder()(50, 75) << endl;
}