2008-11-21 24 views
7

que estoy tratando de declarar y utilizar una clase B dentro de una clase A y definir B fuera A.
Sé que es un hecho de que esto es posible porque Bjarne Stroustrup
utiliza esto en su libro "El lenguaje de programación C++"
(página 293, por ejemplo, las clases String y Srep).C++ clases anidadas error declaración adelantada

Así que este es mi pieza mínima de código 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 da 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 mirar en el C++ PF e closeset Obtuve here y here pero
que no se aplican a mi situación.
También encontré read this pero no resuelve mi problema.

Tanto gcc y MSVC 2005 errores del compilador dan en este

Respuesta

11

Definir el constructor de A después de la definición de la estructura B.

+0

sí, que trabajó gracias :) – xxxxxxx

+0

De nada! :-) –

+1

El constructor se define después de declarar B. Debe definirse después de que se define B. –

15

La expresión c->i desreferencias el puntero a struct A::B por lo que una definición completa debe ser visible en este punto en el 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 struct A::B.

+0

O definir la función como en línea utilizando la palabra clave 'inline' después de la definición de la estructura B. – Phlucious

7

Este es un buen ejemplo de por qué desea mantener definiciones separadas de las declaraciones. Debe 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; 
}
1

Curiosamente, he encontré con el mismo problema con la página 293 ('11 .12 Una clase string) mencionado en el libro BS.

El ejemplo proporcionado en el libro impreso parece ser la culpa, la prestación de los siguientes métodos como en línea, en lugar de definirlos después de la definición de la estructura del 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... 

Googled un poco, y se encontró que el autor de última implementación 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.

Cuestiones relacionadas