Rational
r1(10, 3), // 10/3
r2 = 5; // 5/1
Rational r3 = r1 + r2; // overloaded + … instead of r1.add(r2)
cout << r3 << endl; // overload <<
sets1, s2; // sets of integers — similar high-level semantics to Java's generics s1 += 5; // 'in-place' insertion of 5 into s1 ... Java doesn't have this s2 = s1 + 5; // creates a new set adding 5 to s1 and assigns it to s2 … instead of s2 = s1.add(5);
Integer Wrapper Class
val data member
print function that sends the object's value to a single output, cout
add function that produces and returns a new Integer object containing the
sum of the values of the receiver and argument
result (which will be destroyed upon exit), passing
the constructor the value of the val data member of the receiver.
result's val data member the value of the val data member of
the parameter other
result; a full copy of the object it made since the function uses return by-value
operator
a + b) or the more
conventional function notation (e.g., a.operator +(b) (for a member operator) or
operator +(a, b) (for a non-member operator) — here are some examples:
| Operator Symbol | Function Name | Operator notation | Member Function Notation | Non-member Functional Notation |
|---|---|---|---|---|
| + | operator + | a + b | a.operator +(b) | operator +(a, b) |
| ++ | operator ++ | ++a | a.operator ++() | operator ++(a) |
| = | operator = | a = b | a.operator =(b) | |
| == | operator == | a == b | a.operator ==(b) | operator ==(a, b) |
| [] | operator [] | a[i] | a.operator[](index) | |
| () | operator () | a(i) | a.operator()(...) | |
| -> | operator -> | a -> b | a.operator ->() |
() operator, how is it invoked, and how might
it be useful
<<
==
+, +=
Complex, Matrix to employ conventional notation
=
[]
vector and map) to employ a natural syntax
for modifying/accessing elements
*, ++
()
int C::operator +(Integer rhs)
a in a + b is the receiver (implicit parameter)
b in a + b is the parameter (implicit object parameter)
rhs — usually a name reserved for the right hand side of an assignment, but it's intuitive here, being the
right hand operand of the binary operator.
C:
class C {
friend C operator +(const C &c1, const &c2);
public:
…
C &operator +=(const C &rhs);
private:
int val;
};
we code the above operators in the following manner:
C &C::operator +=(const C &rhs) {
val += rhs.val;
return *this;
}
friend C operator +(const C &c1, const C &c2) {
C temp = c1;
return temp += c2;
}
θ and θ=, which are semantically related; i.e., the latter performs
the same operation as the former, but stores the result into the left hand operand, rather than resulting in a new object):
C &C::operator θ=(const C &c) {
// perform the semantics of the operation
return *this;
}
friend C operator θ(const C &c1, const C &c2) {
C temp = c1;
return temp θ= c2;
}
=)
[])
->)
())
++/--) operators each have two forms -- prefix and postfix. To distinguish
them, the language requires that you supply a dummy int parameter to the prototype of the postfix
(x++) version:
//as non-members
class C1 {...};
void operator ++(C1 &) {...} // e.g. ++c1
void operator ++(C1 &, int) {...} // e.g. c1++
// as members
class C2 {
...
void operator ++() {...} // e.g. ++c2
void operator ++(int) {...} // e.g. c2++
};
class C {
...
C &operator @=(const C &other) { // operator @= (e.g. +=, *=, etc)
.....
}
};
C operator @(const C &c1, const C &c2) {
C result = c1;
return c1 @= c2; // same as c1.operator @=(c2)
}
friend functions in or to maximize
encapsulation (i.e., protecting the class' state from outside manipulation).
friend functions
compare function that returns <0, 0, or >0
as the result of a comparison, and then calling that function from overloaded ==,
!-, <, etc operators
print method, this operator
does not have to be declared as a friend.