Sobrecarga de Operadores: material adaptado de The cplusplus.com tutorial

C++ incorpora la posibilidad de usar operadores estándares con instancias de sus propias clases además del uso común con tipos fundamentales. Por ejemplo:

int a, b, c;
a = b + c;
es perfectamente válido, dado que las variables son todas tipos fundamentales. Sin embargo, no es tan obvio que podemos efectuar la operación siguiente ( de hecho es incorrecto):
struct { char product [50]; float price; } a, b, c;
a = b + c;
Lo que conduce a error es el uso del operador adición, que en principio no es válido entre tipos no fundamentales.

Pero en C++, nosotros podemos hacer que objetos instancias de tipos compuestos como los previos pueden aceptar operadores que de otra manera no serían aceptados. Incluso es posible redefinir el efecto de operadores ya permitidos. La lista de operadores que puede ser sobrecargados es:

+    -    *    /    =    <    >    +=   -=   *=   /=   <<   >>
<<= >>= == != <= >= ++ -- % & ^ ! |
~ &= ^= |= && || %= [] () new delete
Para sobrecargar un operador, sólo necesitamos escribir una función miembro en la clase cuyo nombre es  operator seguido por el signo del operador que queremos sobrecargar, siguiendo este prototipo:
type operator sign (parameters);
Aqui tenemos un ejemplo que incluye eloperador  +. Vamos a sumar vectores bidimensionales a(3,1) y b(1,2)En este caso el resultado será (3+1,1+2) = (4,3).

// vectors: overloading operators example
#include <iostream.h>

class CVector {
  public:
    int x,y;
    CVector () {};
    CVector (int,int);
    CVector operator + (CVector);
};

CVector::CVector (int a, int b) {
  x = a;
  y = b;
}

CVector CVector::operator+ (CVector param) {
  CVector temp;
  temp.x = x + param.x;
  temp.y = y + param.y;
  return (temp);
}

int main () {
  CVector a (3,1);
  CVector b (1,2);
  CVector c;
  c = a + b;
  cout << c.x << "," << c.y;
  return 0;
}
      
4,3

No confundirse por el hecho de ver muchos  CVector. Algunos son el nombre de la clase CVector y otros son nombre de una función con ese nombre (constructor y destructor). 

CVector (int, int);            // function name CVector (constructor)
CVector operator+ (CVector);   // function operator+ that returns CVector type
  
La función operator+ de la clase CVector es la encargada de sobrecargar el operador aritmético  +. Hay dos formas para llamar esta operación:
c = a + b;
c = a.operator+ (b);

Igual como una clase incluye por defecto un constructor de copia y constructor vacío, ésta también incluye un definición por defecto para el operador de asignación (=) entre dos instancias de la misma clase. Éste copia el contenido bit a bit de los miembros no estáticos del objeto de la derecha al de la izquierda.. Por supuesto, podemos redefinir este operador a cualquier otra funcionalidad que se desee; por jemplo, copia en profundidad cuando se tienen miembros datos punteros o en otros casos podriamos desear la copia de sólo algunos datos miembros o atributos.

La sobrecarga de operadores no nos obliga a seguir el mismo significado matemático o usual del operador, aún así es recomendado (por consistencia e interpretación intuitiva). Por ejemplo, no es lógico usar el operador + para restar dos objetos u operador  == para asignar ceros a un objeto, aún cuando esto es posible.

Aún cuando el prototipo de la función operator+ puede resultar obvio, otros operadores pueden no serlo. Aquí se tiene una tabla que resume cómo declarar las diferentes funciones de sobrecarga  (reemplace @ por el operador en cada claso):

Expression Operator (@) Function member Global function
@a + - * & ! ~ ++ -- A::operator@() operator@(A)
a@ ++ -- A::operator@(int) operator@(A, int)
a@b + - * / % ^ & | < > == != <= >= << >> && || , A::operator@(B) operator@(A, B)
a@b = += -= *= /= %= ^= &= |= <<= >>= [ ] A::operator@(B) -
a(b, c...) () A::operator()(B, C...) -
a->b -> A::operator->(B) -
* donde a es un objeto de clase Ab es una instancia de clase B y c es instancia de calse C.
Se puede ver en esta tabla que los operadores se pueden sobrecargar de dos formas: como funciones miembro y como funciones globales. No hay diferencia en su uso, sin embargo hay que recordar que funciones no miembros de la clase no pueden acceder a los miembros  private o protected de una clase a menos que la función global sea declarada  friend en la clase.