11. Operators
Lec 11: Operators¶

When you are using overloaded operators, you are actually calling member functions:
##include <iostream>
##include <vector>
##include <string>
using namespace std;
void human_readable_form() {
vector<string> v{"Hello", "World"};
cout << v[0];
v[1] += "!";
}
void member_function_form() {
vector<string> v{"Hello", "World"};
cout.operator<<(v.operator[](0));
v.operator[](1).operator+=("!");
}
void non_member_function_form() {
// Note: there are some operators that can't be written in non-member-function form.
vector<string> v{"Hello", "World"};
operator<<(cout, operator[](v, 0));
operator+=(operator[](v, 1), "!");
}
A Simple Implementation¶
// ...
class StringVector {
private:
vector<string> data;
public:
StringVector () = default;
StringVector& operator+= (const string& str);
StringVector& operator+= (const StringVector& vec);
// Note: don't use `string& operator[] const (const int& index);`
// Since `const` modifier doesn't allow you to return a
// non-const reference to a member variable
string& operator[] (const int& index);
int size();
};
int StringVector::size()
{
return data.size();
}
// Member function style
StringVector& StringVector::operator+= (const string& str)
{
data.push_back(str);
return *this;
}
StringVector& StringVector::operator+= (const StringVector& vec)
{
data.insert(data.end(), vec.data.cbegin(), vec.data.cend());
return *this;
}
// Non-member function style
string& StringVector::operator[] (const int& index)
{
return data[index];
}
Note: We use const <type>& here, since:
constvalue can't be implicitly converted to non-constone, so we'd better useconst- e.g.
strvec += "Hello","Hello"here isconst(and alsoconstexpr) - Use reference to avoid unnecessary copy.
General Rule of Thumb¶
- Some operators must be implemented as members, e.g.,
[]() -> =, due to C++ semantics. - Some operators must be implemented as non-members, e.g.,
<, if you are writing a class for the right-hand side (rhs), not the left-hand side (lhs). - If it's a unary operator, e.g.,
++, implement it as a member. - If binary operator treats both operands equally (e.g., both unchanged), implement as non-member (maybe friend). Examples:
+,< - If binary operator does not treat both operands equally (changes
lhs), implement as a member (allows easy access tolhsprivate members). Examples:+=
friend modifier¶
Imagine you have a Fraction class:
And you want to use cout to output it. By "General Rule of Thumb", you are writing a class for the rhs (i.e. Fraction instead of ostream), you have to use non-member.
ostream& operator<< (ostream& os, const Fraction& f)
{
// Error! `nom` and `denom` are private!
os << f.nom << "/" << f.denom;
return os;
}
However, nom and denom are private members in Fraction, so it seems that you can't use them in non-members without extra modifier(s).
That's why we have to introduce friend modifier for adding non-member functions to the friends list of the target class.
class Fraction {
private:
int denom;
int nom;
friend ostream& operator<< (ostream& os, const Fraction& f);
};
Const-ness and others¶
Take operator<< as example:
-
ostream&return type, because -
we have to chain
<<'s, soostreamand&(instead ofvoid) -
it will change, so non-
const -
we aren't creating new objects, so
& -
ostream& os, because -
it will change, so non-
const -
const Fraction& f, because -
it will merely be copied and not change, so
const
Principle of Least Astonishment (POLA)¶
"If a necessary feature has a high astonishment factor, it may be necessary to redesign the feature".
- Design operators primarily to mimic conventional usage.
- example 1:
+=returns a reference to the lhs object - counterexample 1: overloading
, - counterexample 2: overloading
+forTimewithsec, min, hour, ..., since we don't know whether+1is adding a sec or a day, etc - Use nonmember functions for symmetric operators.
- to avoid non-symmetric cases like
"char" + str: invalidstr + "char": valid
- Always provide all out of a set of related operators.

- e.g. Implement all
==, !=, <, >, <=, >=, <=>(if the class supports) and not just some of them