Неудивительно, что если включить в myheader.h какое-либо определение, использующее членов
A
, то потребуется включить через
#includ
e заголовок для
А
. Это требуется для того, чтобы компилятор мог проверить сигнатуру используемой функции-члена
А
или тип переменной-члена
А
. Вот иллюстрация кода, требующего
#include
.
#include "a.h"
class B {
public:
void f(const A& a) {
foo_ = a.getVal; //
требуется знать, допустимо ли a.getVal
}
}
// ...
В общем случае используйте предварительное объявление тогда, когда это позволяет снизить количество
#include
, что отражается на времени компиляции.
2.4. Предотвращение конфликта имен с помощью пространств имен
Проблема
В несвязанных между собой модулях обнаружены конфликтующие имена или требуется заранее избежать возможности таких конфликтов, создав логические группы кода.
Решение
Для структурирования кода используйте пространства имен. С помощью пространств имен можно объединять большие группы кода, находящиеся в разных файлах, в единое пространство имен. Для разбиения больших модулей на подмодули можно использовать вложенные пространства имен, и потребители вашего модуля смогут выборочно открывать элементы вашего пространства имен, которые им требуются. Пример 2.5 показывает несколько способов использования пространства имен.
более сложен, но давайте разберем его по частям, так как он иллюстрирует несколько ключевых моментов, связанных с пространствами имен. Представьте, что вы пишете управляющее приложение, которое должно взаимодействовать с различным оборудованием. С целью устранения конфликтов имен вы можете разбить это приложение на два или более пространств имен или просто разделить его логически на две части.
Вначале рассмотрим файл Devices.h. Он содержит пару классов, которые управляют элементами оборудования, —
Device
и
DeviceMgr
. Однако они не должны находиться в глобальном пространстве имен (что означало бы, что их имена видны в любом месте программы), так что я поместил их в пространство имен