2.3. Снижение числа #include с помощью предварительного объявления классов
2.3. Снижение числа #include с помощью предварительного объявления классов
Проблема
Имеется заголовочный файл, который ссылается на классы из других заголовочных файлов, и требуется снизить зависимости компиляции (и, возможно, время).
Решение
Чтобы избежать ненужных зависимостей при компиляции, везде, где только возможно, используйте предварительное объявление классов. Пример 2.4. является коротким примером предварительного объявления класса.
Пример 2.4. Предварительное объявление класса
// myheader.h
#ifndef MYHEADER_H__
#define MYHEADER_H__
class A; // заголовок для А включать не требуется
class В {
public:
void f(const A& a);
// ...
private:
A* a_;
};
#endif
Где-то в другом месте имеется заголовочный файл и, вероятно, файл реализации, который объявляет и определяет класс А, но в файле myheader.h подробности класса А меня не волнуют: все, что мне требуется знать, — это то, что А — это класс.
Обсуждение
Предварительное объявление класса — это способ игнорировать подробности, о которых не требуется беспокоиться. В примере 2.4 myheader.h не должен знать о классе А ничего, кроме того, что он существует и что это класс.
Рассмотрим, что случится, если с помощью #include включить заголовочный файл для А, или, что более реально, заголовочный файл для полудюжины или более классов, присутствующих в реальном заголовочном файле. Тогда файл реализации (myheader.cpp) будет включать заголовочный файл myheader.h, так как он содержит все объявления. До сих пор все было хорошо. Но если вы измените один из заголовочных файлов, включаемых в myheader.h (или один из заголовочных файлов, включаемых одним из этих файлов), то потребуется перекомпилировать все файлы реализации, включающие myheader.h.
Создайте предварительное объявление класса, и эти зависимости компиляции исчезнут. Использование предварительного объявления просто создает имя, на которое можно ссылаться далее в заголовочном файле. Компоновщик должен будет сам найти в файлах реализаций подходящее определение.
К несчастью, использовать предварительное объявление можно не всегда. Класс В в примере 2.4 использует только указатели или ссылки на A, так что ему достаточно только предварительного объявления. Однако если бы в определении класса В я использовал функцию-член (метод) или переменную А или если бы создавал объект типа А, а не только указатель или ссылку на него, то предварительного объявления окажется недостаточно. Причиной этого является то, что файлы, включающие myheader.h, должны знать размер В, и если A является членом В, то компилятор, чтобы определить размер В, должен знать размер А. Указатель или ссылка на что-либо всегда имеют один и тот же размер, так что в случае использования указателей или ссылок подробности об А компилятор не интересуют, и, следовательно, заголовочный файл не требуется
Неудивительно, что если включить в myheader.h какое-либо определение, использующее членов A, то потребуется включить через #include заголовок для А. Это требуется для того, чтобы компилятор мог проверить сигнатуру используемой функции-члена А или тип переменной-члена А. Вот иллюстрация кода, требующего #include.
#include "a.h"
class B {
public:
void f(const A& a) {
foo_ = a.getVal(); // требуется знать, допустимо ли a.getVal
}
}
// ...
В общем случае используйте предварительное объявление тогда, когда это позволяет снизить количество #include, что отражается на времени компиляции.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Каталог Include
Каталог Include В каталоге Include описаны многочисленные файлы. Одни из них используются почти во всех примерах, другие нужны только для одной или двух программ. Перечень наиболее важных файлов приводится ниже.1. EvryThng.h, как говорит само его название, включает почти все
Элемент <xsl:include>
Элемент <xsl:include> Другой способ вставить таблицы стилей внутрь других документов — использовать элемент <xsl:include>, позволяющий включить содержимое файла в определенное место в таблице стилей. У этого элемента только один атрибут:• href (обязательный). URI таблицы
Снижение плотности дефектов
Снижение плотности дефектов FitNesse не является критически важным приложением. Если в FitNesse закрадется ошибка, никто не умрет и никто не потеряет миллионы долларов. Исходя из этого, я могу себе позволить опубликовать новую версию на основании только прохождения тестов. С
include - Импорт текста из внешнего файла ActionScript
include - Импорт текста из внешнего файла ActionScript includeВключает содержимое файла, во время того, как клип тестируется, публикуется или экспортируется.Синтаксис:#include pathАргументы:Директива #include загружает в текущий сценарий текст сценария из внешнего текстового файла
10.13.10 Снижение перегрузок за счет уменьшения пересылаемых по сети данных
10.13.10 Снижение перегрузок за счет уменьшения пересылаемых по сети данных Сокращение объема пересылаемых данных несколько сложнее, чем рассмотренные выше механизмы. Оно начинает работать, как и уже упомянутый медленный старт. Но, поскольку устанавливается граница для
2.2. Снижение издержек на коммуникацию с клиентами
2.2. Снижение издержек на коммуникацию с клиентами Еще раз вспомним, что наибольшие издержки в коммуникации – это время работы живых людей, потому что размер заработной платы сотрудников несравнимо больше стоимости поддержки серверов для того же количества клиентов,
Снижение рисков
Снижение рисков Редко удается полностью устранить риски. Мы водим машину, хоть это и опасно, но ведь нужно добираться до работы? Вообще возможность несчастного случая не означает, что он обязательно произойдет, да и, скорее всего, ничего страшного не случится. Почему?
24. Используйте только внутреннюю, но не внешнюю защиту директивы #include
24. Используйте только внутреннюю, но не внешнюю защиту директивы #include РезюмеПредотвращайте непреднамеренное множественное включение ваших заголовочных файлов директивой #include, используя в них защиту с уникальными именами.ОбсуждениеКаждый заголовочный файл должен
59. Не используйте using для пространств имен в заголовочных файлах или перед директивой #include
59. Не используйте using для пространств имен в заголовочных файлах или перед директивой #include РезюмеДиректива using для пространств имен создана для вашего удобства, а не для головной боли других. Никогда не используйте объявления или директивы using перед директивой #include.Вывод:
Управление созданием базовых классов с помощью base
Управление созданием базовых классов с помощью base В настоящий момент SalesPerson и Manager можно создать только с помощью конструктора, заданного по умолчанию. Поэтому предположим, что в тип Manager добавлен новый конструктор с шестью аргументами, который вызывается так, как
ДИРЕКТИВЫ ПРЕПРОЦЕССОРА #define, #include, #undef, #if, #ifdef, #ifndef, #else, #endif
ДИРЕКТИВЫ ПРЕПРОЦЕССОРА #define, #include, #undef, #if, #ifdef, #ifndef, #else, #endif Язык Си был разработан в помощь работающим программистам, а им нравится его препроцессор. Этот полезный помощник просматривает программу до компилятора (отсюда и термин "препроцессор") и заменяет
ВКЛЮЧЕНИЕ ФАЙЛА: #include
ВКЛЮЧЕНИЕ ФАЙЛА: #include Когда препроцессор "распознает" директиву #include, он ищет следующее за ней имя файла и включает его в текущий файл. Директива выдается в двух видах: #include <stdio.h> имя файла в угловых скобках#include "mystuff.h" имя файла в двойных
16.4. Объявления друзей в шаблонах классов
16.4. Объявления друзей в шаблонах классов 1. обычный (не шаблонный) дружественный класс или дружественная функция. В следующем примере функция foo(), функция-член bar() и класс foobar объявлены друзьями всех конкретизаций шаблона QueueItem:preclass Foo {void bar();};template class Tclass QueueItem {friend class
Окно предварительного просмотра
Окно предварительного просмотра Щелкнув мышью по любому письму в окне заголовков, вы увидите содержание письма в окне предварительного просмотра. А если вы щелкните по заголовку два раза, то письмо откроется полностью в собственном окне (под окном
ГОЛУБЯТНЯ: Плановое снижение градуса
ГОЛУБЯТНЯ: Плановое снижение градуса Автор: Сергей ГолубицкийЗаключительную статью индийского цикла 2009 года посвятим негативным впечатлениям, без которых, конечно же, путешествия в иноземные страны не обходятся в принципе. Индия - не исключение, и, полагаю, составленная