Recientemente me quedé atrapado en una situación como esta:
class A
{
public:
typedef struct/class {...} B;
...
C::D *someField;
}
class C
{
public:
typedef struct/class {...} D;
...
A::B *someField;
}
Por lo general, puede declarar un nombre de clase:
class A;
Pero no puede reenviar la declaración de un tipo anidado, lo siguiente provoca un error de compilación.
class C::D;
¿Algunas ideas?
c++
class
nested
forward-declaration
Calmarius
fuente
fuente
Respuestas:
No puedes hacerlo, es un agujero en el lenguaje C ++. Tendrás que anidar al menos una de las clases anidadas.
fuente
Necesitaba una referencia directa como:
Mi solución fue:
Más tarde, cuando podría usar la definición completa:
Esta técnica probablemente sería más problemática de lo que vale si hubiera constructores complicados u otras funciones miembro especiales que no se heredaran sin problemas. Me imagino que ciertas plantillas mágicas reaccionan mal.
Pero en mi caso muy simple, parece funcionar.
fuente
using basename::basename;
en la clase derivada, por lo tanto, no hay problema con complicados ctors.typedef
dentro de la claseSi realmente quiere evitar #incluir el desagradable archivo de encabezado en su archivo de encabezado, puede hacer esto:
archivo hpp:
archivo cpp
Pero entonces:
Entonces, sí, compensaciones ...
fuente
hpp
archivo?Esto puede hacerse declarando la clase externa como un espacio de nombres .
Muestra: Tenemos que usar una clase anidada others :: A :: Anidado en others_a.h, que está fuera de nuestro control.
otros_a.h
my_class.h
my_class.cpp
fuente
a::b
está maltratada de la misma manera, sin importar sia
es clase o espacio de nombres.No llamaría a esto una respuesta, pero no obstante un hallazgo interesante: si repites la declaración de tu estructura en un espacio de nombre llamado C, todo está bien (al menos en gcc). Cuando se encuentra la definición de clase de C, parece sobrescribir en silencio el espacio nams C.
fuente
Esta sería una solución alternativa (al menos para el problema descrito en la pregunta, no para el problema real, es decir, cuando no se tiene control sobre la definición de
C
):fuente
Si tiene acceso para cambiar el código fuente de las clases C y D, puede extraer la clase D por separado e ingresar un sinónimo en la clase C:
fuente