resolucion programacion orientada operador objetos metodos ejemplos codigo clases ambito c++ class nested declaration forward

programacion - Error de declaración de reenvío de clase anidada en C++



operador de resolucion de ambito c++ (4)

Intento declarar y usar una clase B dentro de una clase A y definir B fuera de A.
Sé con certeza que esto es posible porque Bjarne Stroustrup
usa esto en su libro "El lenguaje de programación C ++"
(página 293, por ejemplo, las clases String y Srep).

Así que este es mi código mínimo que causa problemas

class A{ struct B; // forward declaration B* c; A() { c->i; } }; struct A::B { /* * we define struct B like this becuase it * was first declared in the namespace A */ int i; }; int main() { }

Este código proporciona los siguientes errores de compilación en g ++:

tst.cpp: In constructor ‘A::A()’: tst.cpp:5: error: invalid use of undefined type ‘struct A::B’ tst.cpp:3: error: forward declaration of ‘struct A::B’

Traté de ver el C ++ Faq y el closet que obtuve estaba aquí y aquí, pero
esos no se aplican a mi situación.
También leo esto desde aquí pero no está resolviendo mi problema.

Tanto gcc como MSVC 2005 dan errores de compilación en este


La expresión c->i desreferencia el puntero a la struct A::B por lo que una definición completa debe estar visible en este punto del programa.

La solución más simple es hacer que el constructor de A no esté en línea y proporcionarle un cuerpo después de la definición de la struct A::B


Defina el constructor para A DESPUÉS de la definición de struct B.


Curiosamente, me he topado con el mismo problema con la página 293 (''11 .12 A String Class '') mencionada en el libro de Stroustrup.

El ejemplo provisto en el libro impreso parece ser erróneo, proporcionando los siguientes métodos como en línea, en lugar de definirlos después de la definición de struct Srep

class String { // ... void check(int i) const { if (i<0 || rep->sz <=i) throw Range(); } char read(int i) const { return rep->s[i]; } void write(int i, char c) { rep=rep->get_own_copy(); rep->s[i]=c; } ...etc...

Busqué en Google un poco, y encontré la última implementación del autor de esta clase de cadena, disponible aquí: http://www2.research.att.com/~bs/string_example.c

Parece que lo ha modificado para que estos métodos ya no estén en línea, para evitar el problema mencionado en este hilo.


Este es un buen ejemplo de por qué quiere mantener las definiciones separadas de las declaraciones. Necesita cambiar el orden de las cosas para que el constructor A::A() se defina después de la definición de struct A::B

class A { struct B; B* c; A(); }; struct A::B { int i; }; A::A() { c->i; } int main() { return 0; }