Professional Documents
Culture Documents
• Operator overloading
– Syntax
– Overloadable operators
– Unary operators
– Unusual operators
– Operators you can’t overload
– Overloading new and delete operators
Operator overloading
• Operator is just like any other function, except that the
arguments for this function don’t appear inside
parentheses, but instead they surround or are next to
special characters like +, -, *, /, &, etc.
int main() {
cout << "built-in types:" << endl;
int i = 1, j = 2, k = 3;
k += i + j;
cout << "user-defined types:" << endl;
Integer ii(1), jj(2), kk(3);
kk += ii + jj;
} ///:~
This main function creates 3 objects (ii, jj, kk)
of the new class Integer and then uses them
with overloaded operators ‘+’ and ‘+=‘.
Overloadable operators
// Non-member functions:
class Integer { Global function definitions:
long i; const Integer operator-(const Integer&
Integer* This() { return this; } a) {
public: cout << "-Integer\n";
return Integer(-a.i);
Integer(long ll = 0) : i(ll) {}
}
// No side effects takes const& const Integer operator~(const Integer&
argument: a) {
friend const Integer cout << "~Integer\n";
operator-(const Integer& a); return Integer(~a.i);
friend const Integer }
operator~(const Integer& a);
// Side effects have non-const& Unary – and ~ operators are declared here
argument:
// Prefix:
friend const Integer&
operator++(Integer& a); You have to declare different operators for
// Postfix: prefix and postfix increment and decrement.
friend const Integer When the compiler sees ++a, it generates a
operator++(Integer& a, int);call to operator++(a). When it sees a++,
}; it generates a call to operator++(a, int).
See operator definitions on the next slide.
Prefix and postfix increment
operators
// Prefix; return incremented value
const Integer& operator++(Integer& a) {
cout << "++Integer\n";
a.i++;
return a;
}
// Postfix; return the value before increment:
const Integer operator++(Integer& a, int) {
cout << "Integer++\n";
Integer before(a.i);
a.i++;
return before;
}
Unusual operators
• The subscript, operator[], must be a member function and it requires a single
argument.
• Because operator[] implies that the object it’s being called for acts like an array,
you will often return a reference from this operator, so it can be used on the left
hand-side of an equal sign.
• This operator is commonly overloaded, there will be examples in the following
lectures.
• Operators new and delete will be overloaded in the following lectures as well.
• operator* (dereference)
• You can’t make up operators which don’t exist in the standard operator set.
For example: operator-+
Overloading new and delete
• When you create a new-expression, two things occur:
– First, storage is allocated using the operator new();
– The constructor is called
• In a delete-expression, the destructor is called, then storage is
deallocated using the operator delete().
• You cannot control the constructor and destructor calls.
• You can change the storage allocation functions operator
new() and operator delete().
• In special situations, standard new and delete might not serve your
needs. The common reason to change them is allocator efficiency.
• C++ allows you to overload new and delete to implement your
own storage allocation scheme, so you can handle problems like
this.
Overloading new and delete
int main() {
puts("creating & destroying an int");
int* p = new int(47);
delete p;
puts("creating & destroying an s");
S* s = new S;
delete s;
puts("creating & destroying S[3]");
S* sa = new S[3];
delete []sa;
} ///:~