Как мне объявить внутренний класс?[дубликат]

StackOverflow https://stackoverflow.com/questions/1021793

  •  06-07-2019
  •  | 
  •  

Вопрос

Возможный дубликат:
Форвардное объявление вложенных типов/классов в C++

У меня есть такой класс...

class Container {
public:
    class Iterator {
        ...
    };

    ...
};

В другом месте я хочу передать Container::Iterator по ссылке, но не хочу включать заголовочный файл.Если я попытаюсь объявить класс, я получу ошибки компиляции.

class Container::Iterator;

class Foo {
    void Read(Container::Iterator& it);
};

Компиляция приведенного выше кода дает...

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

Как я могу переслать объявление этого класса, чтобы мне не приходилось включать заголовочный файл, объявляющий класс Iterator?

Это было полезно?

Решение

Это просто невозможно.Вы не можете пересылать объявление вложенной структуры за пределы контейнера.Вы можете объявить его только внутри контейнера.

Вам нужно будет выполнить одно из следующих действий

  • Сделать класс невложенным
  • Измените порядок объявления так, чтобы сначала был полностью определен вложенный класс.
  • Создайте общий базовый класс, который можно будет как использовать в функции, так и реализовать вложенным классом.

Другие советы

Я не верю, что предварительное объявление внутреннего класса в неполном классе работает (потому что без определения класса невозможно узнать, действительно ли является внутренним классом). Таким образом, вам нужно будет включить определение контейнера в заранее объявленный внутренний класс:

class Container {
public:
    class Iterator;
};

Затем в отдельном заголовке внедрите Container :: Iterator:

class Container::Iterator {
};

Затем #include только заголовок контейнера (или не беспокойтесь о прямом объявлении и просто включите оба)

Я не знаю способа сделать именно то, что вы хотите, но вот обходной путь, если вы готовы использовать шаблоны:

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

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

Надеюсь, эта идиома может быть вам полезна (и, надеюсь, ваш компилятор основан на EDG и реализует экспорт;)).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top