Форвардное объявление включает в себя, поверх объявления включают (ClassFwd.h + Class.h) - PullRequest
11 голосов
/ 14 октября 2010

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

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

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

Вот пример:

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

// ClassFwd.h
class Class;

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

Class::~Class()
{
}

Мой вопрос :

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

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

Ответы [ 4 ]

6 голосов
/ 14 октября 2010

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

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

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

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

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

Удачи!

2 голосов
/ 14 октября 2010

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

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

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

Ура & hth.

1 голос
/ 14 октября 2010

Практика позволяет пользователю кода не думать о том, является ли класс обычным или шаблонным.Пользователь только #inlude файл "Соответствующий_fwd.h" и имеет ссылку на класс.Еще одно раздражение для пользователя - A Good Thing.Но если это небольшой проект или класс «создатель - единственный пользователь», то это может вызвать больше раздражения.Итак, это зависит.

0 голосов
/ 14 октября 2010

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

struct A {
    B* m_pB;
};

struct B {
    A* m_pA;
};

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

  1. Сначала включите единственный заголовок Types.h для предварительного объявления для каждого требуемого проекта, т. Е. Для предварительного объявления нет собственного файла заголовка для каждого класса.
  2. Затем включите Class.h всех необходимых проектов.Эти заголовки потребуют предварительных объявлений для компиляции.
  3. Включите заголовки основного проекта.

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

...