2010-09-29 10 views
6

He estado leyendo algunas declaraciones a futuro, incluso en este foro. Todos dicen que nos salva de incluir el archivo de cabecera, pero el siguiente código genera un error:forward declaration genera un error de tipo incompatible

#ifndef CLASSA_H_ 
#define CLASSA_H_ 

class B; 

class A { 

public: 
    A(); 
    ~A(); 
    int getCount(); 
private: 
    static int _count; 
    int _num; 
    B _b1; //ERROR 

}; 

compilador dice: A.h:23: error: field ‘_b1’ has incomplete type

me di cuenta de que si hago _b1 de tipo B* el problema es resuelto

Entonces, ¿la declaración directa es válida solo para los tipos de puntero?
Si quiero A para contener B objeto tengo que #inlcude "B.h"?

gracias!

+0

un poco de auto-promoción: aquí es una respuesta que explica [lo que puede y no puede hacer con tipos incompletas] (http://stackoverflow.com/questions/553682/when-to- use-forward-declaration/553869 # 553869) (es decir, tipos que están declarados pero aún no definidos). –

Respuesta

10

El compilador tiene que conocer la definición exacta de la clase B para determinar al menos qué tamaño para dar a la clase A. Si usa un puntero, conoce su tamaño.

Tenga en cuenta que las dependencias circulares no son posibles. Si quieres

class A { B b; }; 
class B { A a; }; 

entonces A y B deben tener un tamaño infinito ...

+0

+1 Estoy sorprendido de que no supiera eso –

0

Sí, usted tendría que

#include "B.h" 

si desea incluir en su clase B A.

0

Sí, declaraciones adelantadas sólo funcionan si se utiliza punteros y las referencias al tipo de avance declarada . Si usa el objeto por valor, debe incluir el archivo de encabezado completo.

+0

Bueno, las declaraciones hacia adelante funcionarían para usarlo como un tipo en la función _declarations_, también: 'B f (B);' Sin embargo, necesita la definición completa de 'B' para definir _ realmente esta función. – sbi

6

Usted puede utilizar un tipo prospectivas declarada a

  1. punteros de uso y las referencias a ella como miembros de datos
  2. utilícenlo como argumento (incluso tomando por copia) o como tipo de devolución (incluso regresando por copia) para la función declarat iones.

Tendrá una definición completa de un tipo con el fin de

  1. lo utilizan como miembro de la clase de datos
  2. utilizarlo en función de las definiciones .

Si recuerda que un delantero-declaración en realidad es un misnomed declaración (there is no other way of declaring a class type, por lo ninguna declaración de un tipo de clase es una declaración hacia adelante), y que, cada vez que está abriendo las llaves después de class/struct/union identificador además, son definir una clase, todo lo que tiene que recordar es que:

  • necesita una definición completa de utilizar el propio tipo de definiciones
  • salirse con solamente una declaración de utilizar el propio tipo de declaraciones
  • salirse con solamente una declaración cuando se utiliza sólo los punteros y referencias y no trate de miembros de acceso o tipos anidados (cualquier cosa con ., ->, y :: delante)
Cuestiones relacionadas