2011-02-04 2 views
1

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

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

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

Замена форвардной декларации #include "grid.h" works. Но я почему-то думаю, что это уродливо.

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

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

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

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

class Grid::Iterator 

ответ

7

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

+0

Хорошо, простое решение :) Мне просто понравилось, что они вложены, так как они очень тесно связаны с окружающим классом и совершенно бесполезны сами по себе. Можно ли иметь базовый класс (Iterator) и три производных класса (MoreIterator) в одном файле заголовка? –

+0

Конечно, я регулярно ставил десятки классов в один файл заголовка. –

1

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

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

Тогда в вы отделяете каст или заголовочный файл вам нужно будет реализовать ваши вложенные классы следующим образом:

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

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

+0

Хорошая информация, но я думаю, что речь шла о «лучших практиках», –

Смежные вопросы