в том числе вложенные классы - PullRequest
1 голос
/ 04 февраля 2011

У меня есть контейнерный класс с несколькими итераторами в качестве вложенных классов.Структура выглядит примерно так:

class Grid
{
protected:
    class Iterator
    {
        Iterator(Grid* g) : grid(g){}
        Grid* grid;
    }
    class MoreIterator : public Iterator
    {
    }
}

Теперь я хотел переместить итераторы в собственный заголовочный файл, чтобы очистить код контейнеров.

class Grid
{
protected:
#include "griditerators.h"
}

Пока что этокомпилируется без ошибок.Но:

В QtCreator строки

Iterator(Grid* g) : grid(g){}
Grid* grid;

помечены как ошибки, говорящие мне "Сетка не является именем типа".

Я думал, что смогу решить это с помощьюпредварительное объявление в файле griditerator.h:

class Grid;
class Iterator
{
    Iterator(Grid* g) : grid(g){}
    Grid* grid;
}

Но это дает мне ошибку компиляции: Class Grid имеет то же имя, что и класс, в котором он объявлен.

Заменапредварительное объявление с #include "grid.h" работает.Но я почему-то считаю это безобразным.

Так что у меня есть два варианта работы.Один показывает ужасные ошибки в моей IDE, другой мне просто не очень нравится.

Я пробовал другие варианты, где include не входит в класс включения, но не удалось скомпилировать по другим причинам.

Итак, мой вопрос: есть ли "лучшие практики" или шаблоны для обработки вложенных классов, которые слишком велики, чтобы держать их в своем файле классов?

Например, будет лиспособ объявить вложенный класс как:

class Grid::Iterator

Ответы [ 2 ]

7 голосов
/ 04 февраля 2011

Не помещайте объявление вложенного класса в отдельный заголовочный файл.Это плохой дизайн, и он запутает всех, кто должен поддерживать ваш код.Если вложенный класс слишком большой, разверните его и поместите в собственный модуль компиляции (h / cpp combo).

1 голос
/ 23 сентября 2015

Легко добавить реализацию вложенного класса в отдельный файл. Я делаю это все время, но вам все равно нужно объявить вложенный класс в его владельце. Сделайте следующее:

    class Grid
    {
    protected:
        class Iterator;
        class MoreIterator;
    };

Затем в отдельном файле cpp или header вам нужно реализовать вложенные классы следующим образом:

class Grid::Iterator
{
    Iterator(Grid* g) : grid(g){}
    Grid* grid;
}
class Grid::MoreIterator : public Iterator
{
}

Круто то, что классу Grid не нужно знать детали двух вложенных классов, но два вложенных класса знают детали класса Grid и будут иметь права доступа к частным данным в классе Grid, как любой метод, который является членом класса Grid.

...