4.11.4 Ámbito de nombres de clase
§1 Sinopsis
El ámbito de los nombres de clase es local. Comienza en el punto de declaración de la clase y termina el final del bloque en que se ha declarado. Un nombre de clase oculta a cualquier otra clase, objeto, enumerador, o función del mismo nombre en el mismo ámbito, y se exigen ciertas condiciones especiales si el mismo nombre de clase aparece más de una vez en el mismo ámbito.
§2 Si se declara una clase en un ámbito que contenga la declaración de un objeto, función, o enumerador del
mismo nombre, la clase solo puede ser referenciada usando un especificador de tipo, lo que significa que debe utilizarse
uno de los especificadores: class, struct o union junto con el nombre de la clase. Por ejemplo:
struct S { ... };
// declara una clase S de tipo struct
int S(struct S *Sptr); // declara función S, homónima con la clase S
void func(void) {
S t;
// ILEGAL!! la clase S no está visible y no se utiliza
// especificador de tipo
struct S s;
// Ok: se utiliza un especificador de tipo (struct)
S(&s);
// Ok: llamada a función S que es visible
}
§3 Declaración adelantada
Una declaración de clase se dice adelantada o incompleta cuando no se hace la correspondiente definición como en el ejemplo:
class X; // Aún no tiene definición!
La declaración adelantada puede ser útil porque una declaración de este tipo ya permite definir ciertas referencias a la clase declarada (generalmente referencias a punteros-a-objetos de la clase), antes que la misma haya sido completamente definida. Ejemplo:
struct X; // declaración incompleta
struct B { struct X *pa };
struct X { struct B *pb };
La primera ocurrencia de X se llama incompleta porque aún no existe definición en dicho punto. Este tipo de declaración se permite en este caso, porque la declaración de B no precisa del tamaño de X.
§3.1 La declaración adelantada también se suele utilizar en la declaración friend ( 4.11.2a1) de clases, cuando esta declaración es recíproca. Ejemplo:
class B; // L.1: declaración anticipada de B
class A {
...
friend B;
};
...
class B {
...
friend A;
};
En todos los casos la entidad de declaración adelantada debe ser completamente definida antes de poder utilizarla para
otros usos que requieran conocer el tamaño del objeto. Ejemplo:
class B; // declaración adelantada de B
class C; // declaración adelantada de C
class A {
...
friend B; // Ok.
B b1; // Error! clase B no definida aún
friend C::operator* (A&, C&); // Ok!.
};
...
class B {...};
class C {...};
§3.2 typedef (
3.2.1a) no puede ser utilizado con clases de declaración adelantada.
typedef struct COMPLEX; // Ilegal!!
Para más información ver "Declaración de miembros". Ver también las declaraciones adelantadas para las clases VCL.