[ fromfile: functions.xml id: operatoroverloading ]
The keyword operator is used in C++ to define a new meaning for an operator symbol such as +, -, =, *, &, and so forth.
Adding a new meaning to an operator symbol is a specialized form of overloading.
Overloaded operators provide a more compact syntax for calling functions, which can lead to more readable code (assuming the operators are used in ways that are commonly understood).
It is possible to overload nearly all of the existing operator symbols in C++.
For example, suppose that we want to define a class Complex to represent complex numbers
[19].
To specify how to do the basic arithmetic operations with these objects, we could overload the four arithmetic operator symbols.
In addition, we could overload the insertion symbol, <<, so that it uses a more “stream-lined” (if you pardon the pun) interface.
Example 5.6 shows a class definition with both member and non-member operators.
Example 5.6. src/complex/complex.h
#include <iostream>
using namespace std;
class Complex {
// binary non-member friend function declarations
friend ostream& operator<<(ostream& out, const Complex& c);
friend Complex operator-(const Complex& c1, const Complex & c2);
friend Complex operator*(const Complex& c1, const Complex & c2);
friend Complex operator/(const Complex& c1, const Complex & c2);
public:
Complex(double re = 0.0, double im = 0.0);
// binary member function operators
Complex& operator+= (const Complex& c);
Complex& operator-= (const Complex& c);
Complex operator+(const Complex & c2);
private:
double m_Re, m_Im;
};
The operators declared in Example 5.6 are all binary (accept 2 operands).
For the member functions, there is only one formal parameter because the first (left) operand is implicit: *this.
The member operators definitions are shown in Example 5.7.
Example 5.7. src/complex/complex.cpp
[ . . . . ]
Complex& Complex::operator+=(const Complex& c) {
m_Re += c.m_Re;
m_Im += c.m_Im;
return *this;
}
Complex Complex::operator+(const Complex& c2) {
return Complex(m_Re + c2.m_Re, m_Im + c2.m_Im);
}
Complex& Complex::operator-=(const Complex& c) {
m_Re -= c.m_Re;
m_Im -= c.m_Im;
return *this;
}
Example 5.8 shows the definitions of the non-member friend functions. They are defined like ordinary global functions.
Example 5.8. src/complex/complex.cpp
[ . . . . ]
ostream& operator<<(ostream& out, const Complex& c) {
out << '(' << c.m_Re << ',' << c.m_Im << ')' ;
return out;
}
Complex operator-(const Complex& c1, const Complex& c2) {
return Complex(c1.m_Re - c2.m_Re, c1.m_Im - c2.m_Im);
}
We have expressed the mathematical rules that define each of the four algebraic operations in C++ code.
These details are encapsulated and hidden so that client code does not need to deal with them.
Example 5.9 shows some client code that demonstrates and tests the Complex class.
Example 5.9. src/complex/complex-test.cpp
#include "complex.h"
#include <iostream>
int main() {
using namespace std;
Complex c1(3.4, 5.6);
Complex c2(7.8, 1.2);
cout << c1 << " + " << c2 << " = " << c1 + c2 << endl;
cout << c1 << " - " << c2 << " = " << c1 - c2 << endl;
Complex c3 = c1 * c2;
cout << c1 << " * " << c2 << " = " << c3 << endl;
cout << c3 << " / " << c2 << " = " << c3 / c2 << endl;
cout << c3 << " / " << c1 << " = " << c3 / c1 << endl;
return 0;
}
Here is the output of the program in Example 5.9.
(3.4,5.6) + (7.8,1.2) = (11.2,6.8) (3.4,5.6) - (7.8,1.2) = (-4.4,4.4) (3.4,5.6) * (7.8,1.2) = (19.8,47.76) (19.8,47.76) / (7.8,1.2) = (3.4,5.6) (19.8,47.76) / (3.4,5.6) = (7.8,1.2)
There are some limitations on operator overloading.
Only built-in operators can be overloaded.
It is not possible to introduce definitions for symbols such as $ “ ' that do not already possess operator definitions.
Although new meanings can be defined for built-in operators, their associativity and precedence remain the same.
It is possible to overload all of the built-in binary and unary operators except for these:
The ternary conditional operator testExpr ? valueIfTrue : valueIfFalse
The scope resolution operator ::
Member select operators . and .*
| Tip | |
|---|---|
Here is a way you can remember which operators can be overloaded. If it has a dot |
| Note | |
|---|---|
Overloading the comma operator is allowed, but not recommended until you are a C++ expert. |
You can find a complete table of operator symbols and their characteristics in Section 19.1.
[19] Complex numbers were introduced initially to describe the solutions to equations like x2 - 6x + 25 = 0 Using the quadratic formula, one can easily determine that the roots of this equation are 3 + 4i and 3 - 4i.
The complex numbers consist of all numbers of the form: a + bi where a and b are real numbers and i is the square root of -1. Since that set includes such numbers for which b = 0, this shows that the real numbers are a subset of the complex numbers.
| Generated: $Date: 2009-09-08 12:15:32 -0400 (Tue, 08 Sep 2009) $ | © 2009 Alan Ezust and Paul Ezust. |