Espacios de nombres
Variantes

Declaración de clase

De cppreference.com
 
 
 
 

Las clases y estructuras son tipos definidos por el usuario, definidos mediante el especificador de clase, que aparece en la sec-decl-especificadores de la sintaxis de declaración. El especificador de clase tiene la siguiente sintaxis:

clave-de-clase atrib nombre-de-la-clase cláusula-de-base { especificación-de-miembro }
clave-de-clase - Uno de class o struct. Las palabras claves son idénticas excepto por el accesso a miembros por defecto y el acceso a la clase base por defecto.
atrib(C++11) - Secuencia opcional de cualquier número de atributos, puede incluir el especificador alignas.
nombre-de-la-clase - El nombre de la clase que se define. Opcionalmente calificada, opcionalmente seguido de la palabra clave final. El nombre puede omitirse, en cuyo caso la clase no tiene nombre (observa que una clase sin nombre no puede ser final).
cláusula-de-base - Lista opcional de una o más clases base y el modelo de herencia utilizado para cada una (véase clases derivadas)
especificación-de-miembro - Lista de especificadores de acceso, declaraciones y definiciones de objetos miembro y funciones miembro (véase abajo).

Véase clases para una visión general de la sintaxis. Si la clave-de-clase es union, la declaración introduce un tipo unión.

Declaración adelantada

Una declaración de la siguiente forma

clave-de-clase atrib identificador ;

Declara un tipo clase que se definirá más adelante en este ámbito. Hasta que aparezca la definición, este nombre de clase tiene un tipo incompleto. Esto permite que las clases se refieran entre sí:

class Vector; // declaración adelantada
class Matrix {
    // ...
    friend Vector operator*(const Matrix&, const Vector&);
};
class Vector {
    // ...
    friend Vector operator*(const Matrix&, const Vector&);
};

y si un archivo fuente en particular solo usa punteros y referencias a la clase, esto hace posible reducir las dependencias #include:

// en MiEstructura.h 
#include <iosfwd> // contiene declaraciones adelantadas de std::ostream
struct MiEstructura {
    int value;
    friend std::ostream& operator<<(std::ostream& os, const S& s);
    // la definición proporcionada en MiEstructura.cpp file que usa #include <ostream>
};

Si la declaración adelantada aparece en el ámbito local, oculta la clase, la variable, la función y todas las demás declaraciones del mismo nombre previamente declaradas que pueden aparecer en los ámbitos adjuntos:

struct s { int a; };
struct s; // no hace nada (s ya está definida en este ámbito)
void g() {
    struct s; // declaración adelantada de una estructura s nueva, local
              // esto oculta la estructura global shasta el final de este bloque
    s* p;     // puntero a la estructura local s;
    struct s { char* p; }; // definiciones de la estructura local s
}

Observa que un nuevo nombre de clase también puede ser introducido por un especificador de tipo elaborado que aparece como parte de otra declaración, pero solo si la búsqueda de nombre no puede encontrar una clase previamente declarada con el mismo nombre.

class U;
namespace ns{