Pytanie w sprawie c++, forward-declaration – Jak przekazać deklarację klasy wewnętrznej? [duplikować]

133

Możliwy duplikat:
Forward deklaracja zagnieżdżonych typów / klas w C ++

Mam taką klasę ...

<code>class Container {
public:
    class Iterator {
        ...
    };

    ...
};
</code>

Gdzie indziej chcę przekazać Container :: Iterator przez odwołanie, ale nie chcę dołączać pliku nagłówkowego. Jeśli spróbuję przekazać deklarację klasy, otrzymuję błędy kompilacji.

<code>class Container::Iterator;

class Foo {
    void Read(Container::Iterator& it);
};
</code>

Kompilacja powyższego kodu daje ...

<code>test.h:3: error: ‘Iterator’ in class ‘Container’ does not name a type
test.h:5: error: variable or field ‘Foo’ declared void
test.h:5: error: incomplete type ‘Container’ used in nested name specifier
test.h:5: error: ‘it’ was not declared in this scope
</code>

Jak mogę przekazać deklarację tej klasy, więc nie muszę dołączać pliku nagłówkowego, który deklaruje klasę Iteratora?

Znalazłem rozwiązaniepołączyć bitlixi

Twoja odpowiedź

3   odpowiedź
1

jak zrobić dokładnie to, co chcesz, ale tutaj jest obejście, jeśli chcesz użyć szablonów:

<code>// Foo.h  
struct Foo
{
   export template<class T> void Read(T it);
};
</code>
<code>// Foo.cpp
#include "Foo.h"
#include "Container.h"
/*
struct Container
{
    struct Inner { };
};
*/
export template<> 
  void Foo::Read<Container::Inner>(Container::Inner& it)
{

}
</code>
<code>#include "Foo.h"
int main()
{
  Foo f;
  Container::Inner i;
  f.Read(i);  // ok
  f.Read(3);  // error
}
</code>

Mam nadzieję, że ten idiom może Ci się przydać (i mam nadzieję, że twój kompilator jest oparty na EDG i implementuje eksport;)).

20

aby dalej deklarować klasę wewnętrzną na niekompletnej klasie działa (ponieważ bez definicji klasy, nie ma sposobu, aby wiedzieć, czy rzeczywiście istniejejest klasa wewnętrzna). Musisz więc dołączyć definicję kontenera z zadeklarowaną klasą wewnętrzną:

<code>class Container {
public:
    class Iterator;
};
</code>

Następnie w osobnym nagłówku zaimplementuj Kontener :: Iterator:

<code>class Container::Iterator {
};
</code>

Następnie #include tylko nagłówek kontenera (lub nie martw się o zgłaszanie do przodu i po prostu dołącz oba)

Dobra odpowiedź, z wyjątkiem części w nawiasie pierwszego akapitu. „Nie ma sposobu, aby wiedzieć, czy rzeczywiście istnieje klasa wewnętrzna”, nie ma sensu w tym kontekście i jest wątpliwe, aby być dokładnym. Istotą deklaracji forward jest to, że mówisz kompilatorowi, że istnieje klasa (lub w tym przypadku klasa wewnętrzna). To twoje konkretne stwierdzenie byłoby tak samo prawdziwe dla zwykłych klas i oznaczałoby, że nie możesz przekazać niczego. Loduwijk
117

ej struktury poza kontenerem. Możesz przekazać go tylko do przodu w kontenerze.

Musisz wykonać jedną z następujących czynności

Niech klasa nie jest zagnieżdżonaZmień kolejność deklaracji, aby zagnieżdżona klasa była w pełni zdefiniowana jako pierwszaUtwórz wspólną klasę bazową, która może być używana zarówno w funkcji, jak i zaimplementowana przez klasę zagnieżdżoną.
Możesz użyć przyjaciela do obejścia tego, jeśli chcesz. Erik Aronesty
Wspólna klasa bazowa jest rozwiązaniem najczęściej używanym na moim końcu. Coyote
Fakt, że niemożliwe jest przekazanie deklarowanej zagnieżdżonej struktury poza kontenerem, wydaje się być ograniczeniem w C ++ i czymś, co powinno być możliwe. Dobrze? Czy jest jakiś powód, dla którego nie jest to możliwe? HelloGoodbye
@Nikerboker twierdzą, że zagnieżdżone klasy nie mogą być przekazywane do przoduna zewnątrz pojemnik. Przykład w linku jest przekazywany dalej, deklarując klasę zagnieżdżonąwewnątrz definicji kontenera, co jest innym scenariuszem. Antonio Barreto

Powiązane pytania