2010-12-02 12 views
10

Cuando las declaraciones de funciones avanzan en un archivo de origen (.cpp), ¿por qué no funciona lo mismo para las clases?Reenviar declaración de clase, función

Gracias.

// main.cpp 

void forwardDeclaredFunction() ; // This is correct 

class One ; // Why this would be wrong 

int One:: statVar = 10 ; 

void 
One :: anyAccess() { 

std::cout << "\n statVar:\t " << statVar ; 
std::cout << "\n classVar:\t" << classVar ; 
} 

class One { 

public: 
    void anyAccess() ; 
    static int statVar ; 

private: 
    int classVar ; 

} ; 


int main (int argc, char * const argv[]) { 

One *obj = new One ; 

     return 0; 
} 

void forwardDeclaredFunction() { 
} 
+3

'class One;' es la sintaxis correcta para una declaración de clase forward. ¿Qué mensaje de error del compilador estás recibiendo, exactamente? –

+1

error: uso no válido del tipo incompleto Struct One; Me estoy ejecutando en Mac – Mahesh

Respuesta

11

declaración adelantada puede trabajar para las clases también:

class Foo; 

class Bar { 
public: 
    Foo *myFoo; // This has to be a pointer, thanks for catching this! 
}; 

class Foo { 
public: 
    int value; 
}; 

El código anterior muestra una declaración de avance de la clase Foo, utilizando una variable de tipo Foo * en otra clase (Bar), entonces la definición real de la clase Foo. A C++ no le importa si deja las cosas sin implementar siempre que las implemente antes de usar su código. Definir punteros a objetos de cierto tipo no es "usar su código".

Respuesta rápida y sucia, pero espero que ayude.

Editar: Declarar una variable no puntero de una clase que no se implemente NO compilará como las respuestas establecidas. Hacerlo es exactamente lo que quise decir con "usar su código". En este caso, se llamará al constructor de Foo siempre que se llame al constructor de Bar, dado que tiene una variable miembro de tipo Foo. Como el compilador no sabe que planea implementar Foo más tarde, generará un error. Lo siento por mi error ;).

+2

AFAIK, las declaraciones de reenvío no le permiten tener objetos de la clase declarada, solo punteros y posiblemente referencias. En su ejemplo, el compilador aún no puede saber 'sizeof (Foo)', por lo que es imposible definir 'Bar'. – cHao

+2

Esto no compilará por la misma razón que falla el código de OP: está utilizando Foo antes de que se conozca su estructura completa (gcc le dirá "campo 'myFoo' tiene tipo incompleto") – Lars

+1

No olvide que también puede declarar una referencia , habiendo solo declarado su tipo, por ejemplo: 'const Foo & myFoo'. –

3

Coloque su declaración de miembro de su clase antes de las implementaciones miembro.

class One { 

public: 
    void anyAccess() ; 
    static int statVar ; 

private: 
    int classVar ; 

} ; 

int One:: statVar = 10 ; 

void 
One :: anyAccess() { 

std::cout << "\n statVar:\t " << statVar ; 
std::cout << "\n classVar:\t" << classVar ; 
} 
5

La declaración adelantada class One; le permite referirse a la clase sí, pero no a cualquiera de sus miembros. Debes poner todas las definiciones de los miembros de la clase después de la declaración completa de la clase. (O dentro, por supuesto.)

2

Aparecerá el mensaje de error en int One:: statVar = 10 ; NO en la declaración directa, lo cual está bien.

El compilador necesita conocer la definición completa de la clase antes de poder definir miembros estáticos como eso - una declaración directa es insuficiente (necesita poder confirmar que el tipo es correcto desde la definición de la clase).

Tendrá que mover su definición de atributo estático por debajo de la definición de la clase.

2

El compilador lee cosas de principio a fin, y genera código a medida que avanza. (Algunos compiladores pueden no hacer esto, pero deberían comportarse como si lo hicieran). Pero antes de que se defina la clase, el compilador no sabe que One::statVar o One::anyAccess deberían existir, o si la función es virtual, estática o qué. Necesita saber eso para generar código.

0

cuando se crea la clase 2 & una función puede acceder a datos de la clase a otra clase entonces es una función friend

declaración forword es el uso de saber qué clase en la próxima clase ABC

;

xyz clase

{

miembro de datos;

pública:

amigo vacío leedato();

otro miembro de la función

}

clase ABC

{

miembro de datos

pública:

amigo vacío leedato();

}

Cuestiones relacionadas