Por defecto, use funciones de espacio de nombres.
Las clases son para construir objetos, no para reemplazar espacios de nombres.
En código orientado a objetos
Scott Meyers escribió un artículo completo para su libro eficaz de C ++ sobre este tema, "Prefiero funciones que no sean miembros y no amigos a funciones miembros". Encontré una referencia en línea a este principio en un artículo de Herb Sutter:http://www.gotw.ca/gotw/084.htm
Lo importante es saber que: en C ++, las funciones en el mismo espacio de nombres que una clase pertenecen a la interfaz de esa clase (porque ADL buscará esas funciones al resolver llamadas de función).
Las funciones de espacio de nombres, a menos que se declare "amigo", no tienen acceso a los elementos internos de la clase, mientras que los métodos estáticos sí.
Esto significa, por ejemplo, que al mantener su clase, si necesita cambiar los elementos internos de su clase, deberá buscar los efectos secundarios en todos sus métodos, incluidos los estáticos.
Extensión I
Agregar código a la interfaz de una clase.
En C #, puede agregar métodos a una clase incluso si no tiene acceso a ella. Pero en C ++, esto es imposible.
Pero, aún en C ++, aún puede agregar una función de espacio de nombres, incluso a una clase que alguien escribió para usted.
Vea desde el otro lado, esto es importante al diseñar su código, porque al poner sus funciones en un espacio de nombres, autorizará a sus usuarios a aumentar / completar la interfaz de la clase.
Extensión II
Como efecto secundario del punto anterior, es imposible declarar métodos estáticos en múltiples encabezados. Todos los métodos deben declararse en la misma clase.
Para espacios de nombres, las funciones del mismo espacio de nombres se pueden declarar en varios encabezados (la función de intercambio casi estándar es el mejor ejemplo de eso).
Extensión III
La frescura básica de un espacio de nombres es que en algún código, puede evitar mencionarlo, si usa la palabra clave "using":
#include <string>
#include <vector>
// Etc.
{
using namespace std ;
// Now, everything from std is accessible without qualification
string s ; // Ok
vector v ; // Ok
}
string ss ; // COMPILATION ERROR
vector vv ; // COMPILATION ERROR
E incluso puede limitar la "contaminación" a una clase:
#include <string>
#include <vector>
{
using std::string ;
string s ; // Ok
vector v ; // COMPILATION ERROR
}
string ss ; // COMPILATION ERROR
vector vv ; // COMPILATION ERROR
Este "patrón" es obligatorio para el uso adecuado del lenguaje de intercambio casi estándar.
Y esto es imposible de hacer con métodos estáticos en las clases.
Por lo tanto, los espacios de nombres C ++ tienen su propia semántica.
Pero va más allá, ya que puede combinar espacios de nombres de forma similar a la herencia.
Por ejemplo, si tiene un espacio de nombres A con una función AAA, un espacio de nombres B con una función BBB, puede declarar un espacio de nombres C y traer AAA y BBB en este espacio de nombres con la palabra clave usando.
Conclusión
Los espacios de nombres son para espacios de nombres. Las clases son para clases.
C ++ fue diseñado para que cada concepto sea diferente y se use de manera diferente, en diferentes casos, como una solución a diferentes problemas.
No use clases cuando necesite espacios de nombres.
Y en su caso, necesita espacios de nombres.