2011-11-17 24 views
5

que puede declarar un puntero a una clase que aún no se ha definido, como esto:Declarar clases anidadas antes de ser definidas

class A ; 
A* p ; 

pero ¿cómo puedo hacer esto para una clase anidada? Quiero hacer esto:

class A ; 
class A::B ; // error: 'B' in class 'A' does not name a type 
A::B* p ; 

Pero no se compila (usando g ++ 4.5.2). ¿Hay alguna manera de hacer funcionar esto?

+0

Simplemente no anide B si lo necesita. (Puede agrupar clases con espacios de nombres. Anidar - al menos en C++ 03 - no agrega ningún otro valor.) – visitor

+0

No es posible hasta que se haya definido la clase 'A '. Debe rediseñar para no utilizar clases anidadas hasta después de la definición de la clase que contiene la clase anidada. –

+0

Ver también [¿Hay una forma más corta de reenviar declarar una clase en un espacio de nombres?] (Http://stackoverflow.com/questions/1368642). – outis

Respuesta

4

Hay una serie de partes de C++ 03 que no permiten las declaraciones de anidación de clases anidadas. En particular, § 7.1.5.3 elaborados especificadores de tipo:

  1. Si un elaborados de tipo especificador es el único constituyente de una declaración, la declaración está mal formada, a menos que se trata de una especialización explícita (14.7.3), una instanciación explícita (14.7.2) o que tiene una de las siguientes formas:

    class-keyidentifier ; 
    friend class-key ::optidentifier ; 
    friend class-key ::opttemplate-id ; 
    friend class-key ::optnested-name-specifieridentifier ; 
    friend class-key ::optnested-name-specifiertemplateopt 
    template-id ; 
    
  2. 3.4.4 describe cómo producto de búsqueda de nombres para el identificador en una elaborado-tipo-especificador. Si el identificador se resuelve en un clase- o enumeración de nombres, la elaborados de tipo especificador introduce en la declaración de la misma forma en que un -tipo simple especificador presenta su nombre-tipo. [...] Si la búsqueda de nombre no encuentra una declaración para el nombre, el especificador de tipo elaborado está mal formado a menos que sea del formulario simple clave de clase identificador en cuyo caso el identificador es declarado como se describe en 3.3.1.

En resumen, cuando está en el ámbito de un identificador, el compilador debe tratar de resolver el identificador. Cuando el alcance es una clase, el compilador debe buscar la declaración del identificador en la clase externa. Cuando la clase externa aún no se ha definido, no se puede hacer y el resultado es un programa mal formado.

3

Considere un espacio de nombres en lugar de la clase anidada.

class A; 
A * pa; 
namespace A_help 
{ 
    class B; 
} // namespace A_help 
A_help::B * pb; 
Cuestiones relacionadas