The World of C++, part 2

Namespaces

Problem:

// A.h
class foo { … };
// B.h
class foo { … };
// use.cpp
#include “A.h”
#include “B.h” // Clash of class definitions!

Solution:

// A.h
namespace A { // Global scoping
class foo { … };
}
// B.h
namespace B { // Global scoping
class foo { … };
}
// use.cpp
#include “A” // No suffix “.h” when the header contains a namespace
#include “B” // No clash!
A::foo objectFoo1;
B::foo objectFoo2;

Operator overloading

(x + y) is equivalent to

x.operator+(y) // Member function

OR

operator+(x,y) // Non-member function
Chaining of operators is also possible:
x + y + z

is equivalent to

((x + y) + z)

OR

(x.operator+(y)).operator+(z)
Signature:
A operator+(const A& other);

Assignment operator:

x = y = z

is equivalent to:

x = (y = z)

OR

x.operator=(y.operator=(z))
Signature:
A& operator=(const A& other);

Standard input:

std::cin >> x >> y

is equivalent to:

operator>>(operator>>(std::cin, x), y)
Signature (must be a non-member function):
std::istream& operator>>(std::istream& s, A& a)

Standard output:

std::cout << x << y

is equivalent to

operator<<(operator<<(std::cout, x), y)
Signature (must be a non-member function):
std::ostream& operator<<(std::ostream& s, const A& a);

Prefix/postfix operators:

++x is equivalent to

x.operator++()

x++ is equivalent to

x.operator++(0) // 0 is irrelevant but used for function overloading

++(++x) is equivalent to

x.operator++().operator++()

(x++)++ is NOT legal.

A& operator++() // Prefix
{
  // Increment logic
  return *this;
}
A operator++(int) // Postfix
{
  A result(*this); // Copy constructor called
  ++(*this);  // Prefix operator function invoked
  return result;
}

Subscripting:

A a;
MemberType m;
a[i] = m; // equivalent to a.operator[](i) = m
const A a;
a[i] = m; // illegal
Signatures:
const MemberType& operator[](int index) const; // Receiver is a const
MemberType& operator[](int index); // Receiver is a not const