2010-08-31 21 views
12

Acabo de empezar a programar en C++, y he intentado crear 2 clases donde una contendrá la otra.Nombre de clase no nombra un tipo en C++

Archivo A.h:

#ifndef _A_h 
#define _A_h 

class A{ 
    public: 
     A(int id); 
    private: 
     int _id; 
     B _b; // HERE I GET A COMPILATION ERROR: B does not name a type 
}; 

#endif 

Archivo A.cpp:

#include "A.h" 
#include "B.h" 
#include <cstdio> 

A::A(int id): _id(id), _b(){ 
    printf("hello\n the id is: %d\n", _id); 
} 

Archivo B.h:

#ifndef _B_h 
#define _B_h 

class B{ 
    public: 
     B(); 
}; 
#endif 

Archivo B.cpp:

#include "B.h" 
#include <cstdio> 

B::B(){ 
    printf("this is hello from B\n"); 
} 

primera vez que compilar la clase B y luego la clase A, pero luego me sale el mensaje de error:

A.h:9: error: ‘B’ does not name a type

¿Cómo puedo solucionar este problema?

+0

@Georg ¿por qué pusiste todo en un segmento de código? Son archivos diferentes. –

+0

@Amir: Parecía roto antes de hacer clic en * editar * y estaba distraído :) –

+0

Puede aceptar una de las respuestas que encontró más útiles haciendo clic en la marca de verificación además de la respuesta. Esto será útil para otras personas que tendrán el problema similar. – Naveen

Respuesta

25

El preprocesador inserta el contenido de los archivos A.h y B.h exactamente donde se produce la declaración include (esto es sólo copiar/pegar). Cuando el compilador analiza el A.cpp, encuentra la declaración de la clase A antes de conocer la clase B. Esto causa el error que ves. Hay dos maneras de resolver este:

  1. Incluir B.h en A.h. En general, es una buena idea incluir archivos de encabezado en los archivos donde se necesitan. Si confía en la inclusión indirecta mediante otro encabezado, o una orden especial de inclusión en la unidad de compilación (archivo cpp), esto solo lo confundirá a usted y a los demás a medida que el proyecto crezca.
  2. Si utiliza variable miembro de tipo B en clase A, el compilador necesita conocer la declaración exacta y completa de B, ya que necesita para crear la memoria de diseño para A. Si, por otro lado, estaba usando un puntero o referencia a B, entonces una declaración directa sería suficiente, porque la memoria que el compilador necesita reservar para un puntero o referencia es independiente de la definición de la clase. Esto se vería así:

    class B; // forward declaration   
    class A { 
    public: 
        A(int id); 
    private: 
        int _id; 
        B & _b; 
    }; 
    

    Esto es muy útil para evitar las dependencias circulares entre los encabezados.

Espero que esto ayude.

2

Incluir "B.h" en "A.h". Eso trae la declaración de 'B' para el compilador al compilar 'A'.

La primera viñeta se cumple en el caso de OP.

$ 3.4.1/7 -

"A name used in the definition of a class X outside of a member function body or nested class definition27) shall be declared in one of the following ways:

before its use in class X or be a member of a base class of X (10.2), or

— if X is a nested class of class Y (9.7), before the definition of X in Y, or shall be a member of a base class of Y (this lookup applies in turn to Y’s enclosing classes, starting with the innermost enclosing class),28) or

— if X is a local class (9.8) or is a nested class of a local class, before the definition of class X in a block enclosing the definition of class X, or

— if X is a member of namespace N, or is a nested class of a class that is a member of N, or is a local class or a nested class within a local class of a function that is a member of N, before the definition of class X in namespace N or in one of N’s enclosing namespaces."

3

Debe incluir primera B.h de A.h. B b; no tiene sentido hasta que haya incluido B.h.

2

El problema es que debe incluir B.h en su archivo A.h. El problema es que en la definición de A, el compilador aún no sabe qué es B. Debe incluir todas las definiciones de todos los tipos que está utilizando.

1

cuando se define la clase A, en Ah, que explícitamente decir que la clase tiene un miembro B.

Usted debe incluir "Bh" en "Ah"

1

no ¿Le falta el # incluir "Bh" en Ah?

2
error 'Class' does not name a type 

Por si alguien hace lo mismo idiota que hice ... estaba creando un pequeño programa de prueba de cero y he escrito Clase en lugar de clase (con una pequeña C). No tomé nota de las citas en el mensaje de error y pasé demasiado tiempo sin entender mi problema.

Mi búsqueda de una solución me trajo aquí, así que supongo que lo mismo podría pasarle a otra persona.

Cuestiones relacionadas