while que programacion funcionan for estructura definicion como ciclos ciclo anidar anidados anidado algoritmos c++ class nested forward-declaration

c++ - que - for anidados como funcionan



DeclaraciĆ³n directa de tipos/clases anidados en C++ (5)

Esto 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 ):

class C_base { public: class D { }; // definition of C::D // can also just be forward declared, if it needs members of A or A::B }; class A { public: class B { }; C_base::D *someField; // need to call it C_base::D here }; class C : public C_base { // inherits C_base::D public: // Danger: Do not redeclare class D here!! // Depending on your compiler flags, you may not even get a warning // class D { }; A::B *someField; }; int main() { A a; C::D * test = a.someField; // here it can be called C::D }

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; }

Usualmente puedes declarar un nombre de clase:

class A;

Pero no puede reenviar declarar un tipo anidado, lo siguiente causa un error de compilación.

class C::D;

¿Algunas ideas?


No lo llamaría una respuesta, pero sin embargo es un hallazgo interesante: si repites la declaración de tu estructura en un espacio de nombres llamado C, todo está bien (al menos en gcc). Cuando se encuentra la definición de clase de C, parece sobrescribir silenciosamente el namspace C.

namespace C { typedef struct {} D; } class A { public: typedef struct/class {...} B; ... C::D *someField; } class C { public: typedef struct/class {...} D; ... A::B *someField; }


No puedes hacerlo, es un agujero en el lenguaje C ++. Deberá anular la anotación de al menos una de las clases anidadas.


Si realmente desea evitar #incluir el desagradable archivo de encabezado en su archivo de encabezado, puede hacer esto:

archivo hpp:

class MyClass { public: template<typename ThrowAway> void doesStuff(); };

archivo cpp

#include "MyClass.hpp" #include "Annoying-3rd-party.hpp" template<> void MyClass::doesStuff<This::Is::An::Embedded::Type>() { // ... }

Pero entonces:

  1. tendrá que especificar el tipo incrustado en el momento de la llamada (especialmente si su función no toma ningún parámetro del tipo incrustado)
  2. su función no puede ser virtual (porque es una plantilla)

Entonces, sí, intercambios ...


class IDontControl { class Nested { Nested(int i); }; };

Necesitaba una referencia directa como:

class IDontControl::Nested; // But this doesn''t work.

Mi solución fue:

class IDontControl_Nested; // Forward reference to distinct name.

Más tarde, cuando pude usar la definición completa:

#include <idontcontrol.h> // I defined the forward ref like this: class IDontControl_Nested : public IDontControl::Nested { // Needed to make a forwarding constructor here IDontControl_Nested(int i) : Nested(i) { } };

Esta técnica probablemente sería más problemática de lo que vale si hubiera constructores complicados u otras funciones especiales de miembros que no se heredaran sin problemas. Pude imaginar que cierta magia de plantilla reaccionaba mal.

Pero en mi caso muy simple, parece funcionar.