Подтвердить что ты не робот

Объявление вперед включает, помимо объявления include (ClassFwd.h + Class.h)

В Effective С++ (3-е издание) Скотт Мейерс в пункте 31 предполагает, что классы должны иметь, помимо своих классических файлов декларации (.h) и определения (.cpp), файл декларации Forward Forward Include File (fwd. h), какой класс, который не нуждается в полном определении, может использовать, а не наоборот, объявляя себя.

Я кое-что вижу в этом случае, но я действительно не вижу в этом жизнеспособного варианта... Кажется, очень сложно поддерживать, а скорее излишне и вряд ли необходимо.

Я могу, однако, увидеть его использование для форвардных деклараций шаблонов, которые довольно тяжелы. Но для простых классов? Похоже, что это боль для поддержания и создания множества почти пустых файлов, которые служат очень маленькой цели... стоит ли хлопот?

Вот пример:

// Class.h
class Class
{
    Class();
    ~Class();
};

// ClassFwd.h
class Class;

// Class.cpp
Class::Class()
{
}

Class::~Class()
{
}

Мой вопрос:

Что вы, ребята, думаете? Если это хорошая практика?

ПРИМЕЧАНИЕ Меня больше интересуют аргументы для этой практики, чтобы увидеть, пропустил ли я что-то, что позволило бы мне согласиться с Скоттом Мейерсом.

4b9b3361

Ответ 1

Я использовал файлы заголовков деклараций для всех моих библиотек. Обычно библиотека имеет такую ​​структуру:

lib/
  include/
    class headers + Fwd.h
src/
  source files + internal headers

Каталог lib/include будет содержать все заголовки общих классов вместе с одним заголовком форвардных объявлений. Это сделало библиотеку легкой на стороне включения. Любой заголовок вне этой библиотеки включает только прямой заголовок (Fwd.h), а источники за пределами этой библиотеки содержат необходимые полные заголовки. Можно также предоставить заголовок удобства (Lib.h), который включает все остальные заголовки, для использования в исходных файлах.

Еще одна вещь, которую нужно поместить в заголовок прямой декларации, - typedef для shared_ptr, особенно в случае иерархии наследования с классами factory, которые возвращают указатели на реализации.

Вышеприведенное полезно для больших приложений с большим количеством внутренних библиотек. Уточнение вышеприведенного для этого случая было бы поместить публичные заголовки в lib/include/lib. Таким образом, клиенты вашей библиотеки должны будут включать lib/.... Подумайте об этом как о пространстве имен для ваших заголовков.

Удачи!

Ответ 2

Размещение простого class Whatever; в собственном заголовке не имеет преимуществ и большого количества недостатков.

Особенно в случае, когда доступ к заголовку может занять много времени, в нем используются простые форвардные объявления, чтобы избежать доступа к заголовкам; помещая их в свои собственные заголовки, победит цель...

С шаблонами, как вы заметили, это другое дело. Например. проверьте <iosfwd> из стандартной библиотеки.

Приветствия и hth.

Ответ 3

Практика позволяет пользователю кода не думать о том, является ли класс регулярным или шаблонным. Пользователь просто # включает файл "соответствующий_fwd.h" и имеет ссылку на класс. Еще одно раздражение для пользователя - это хорошая вещь. Но если это небольшой проект или создатель класса является единственным пользователем класса, тогда это может быть более раздражающим. Таким образом, это зависит.

Ответ 4

Если у вас есть большое решение, это ваш единственный шанс обработать неотъемлемые зависимости:

struct A {
    B* m_pB;
};

struct B {
    A* m_pA;
};

Теперь A и B могут быть в разных заголовочных файлах, возможно, даже в разных проектах. Тем не менее, их зависимость - это не какой-то дефект дизайна, а вполне логичный и необходимый. Чем ты занимаешься?

  • Сначала включите один заголовок Forward.h для заголовка. для требуемого проекта eeach, т.е. в прямом объявлении нет собственного файла заголовка для каждого класса.
  • Затем включите Class.h всех необходимых проектов. Для этих заголовков потребуются форвардные декларации для компиляции.
  • Включить заголовки основного проекта.

В довольно большом решении (500K LOC) я нашел этот шаблон очень легко управляемым. В противном случае, если вы измените объявление класса, где вы найдете все объявления вперед, которые могут быть сделаны индивидуально в любом количестве других файлов заголовков?