Читаем Стандарты программирования на С++ полностью

Когда вы определяете два объекта уровня пространства имен в разных единицах компиляции, конструктор какого из объектов будет вызван первым, не определено. Чаще всего (но не всегда) ваш инструментарий будет инициализировать их в том порядке, в котором компонуются скомпилированные объектные файлы, но полагаться на это предположение нельзя, даже если оно и выполняется, — вы же не хотите, чтобы корректность вашей программы зависела от вашего файла проекта или makefilе (дополнительную информацию о неприятностях, связанных с зависимостью от порядка, можно почерпнуть в рекомендации 59).

Таким образом, в коде инициализации любого объекта уровня пространства имен вы не можете полагаться на то, что уже инициализирован некоторый объект, определенный в другой единице компиляции. Это же касается и динамически инициализируемых переменных примитивных типов (пример такого кода на уровне пространства имен: bool reg_success = LibRegister("mylib");).

Заметим, что еще до того, как будет вызван конструктор, объект на уровне пространства имен статически инициализируется нулями (в отличие от, скажем, автоматического объекта, который обычно содержит мусор). Парадоксально, но эта инициализация нулями может затруднить обнаружение ошибки, поскольку вместо аварийного завершения программы такой заполненный нулями (но на самом деле неинициализированный) объект создает видимость корректности. Вам кажется, что строка пуста, указатель имеет нулевое значение, целое число равно нулю, — в то время как на самом деле никакой код еще и не пытался инициализировать ваши объекты.

Чтобы решить эту проблему, избегайте переменных уровня пространства имен везде, где только можно; такие переменные — вообще опасная практика (см. рекомендацию 10). Если вам нужна такая переменная, которая может зависеть от другой, подумайте о применении шаблона проектирования Singleton; при аккуратном его использовании можно избежать неявных зависимостей, обеспечивая инициализацию объекта при его первом использовании. Singleton остается глобальной переменной в шкуре овцы (еще раз см. рекомендацию 10), и не работает при взаимных или циклических зависимостях (и здесь инициализация нулями также способствует общей неразберихе).

Ссылки

[Dewhurst03] §55 • [Gamma95] • [McConnell93] §5.1-4 • [Stroustrup00] §9.4.1, §10.4.9

<p>22. Минимизируйте зависимости определений и избегайте циклических зависимостей</p>Резюме

Избегайте излишних зависимостей. Не включайте при помощи директивы #include определения там, где достаточно предварительного объявления.

Избегайте взаимозависимостей. Циклические зависимости возникают, когда два модуля непосредственно или опосредованно зависят друг от друга. Модуль представляет собой обособленную единицу; взаимозависимые модули не являются полностью отдельными модулями, будучи по сути частями одного большего модуля. Таким образом, циклические зависимости являются противниками модульности и представляют угрозу большим проектам. Избегайте их.

Обсуждение

Предпочитайте использовать предварительные объявления везде, где не требуется полное определение типа. Полное определение класса С требуется в двух основных случаях.

• Когда вам необходимо знать размер объекта С. Например, при создании объекта С в стеке или при использовании его в качестве непосредственно хранимого (не через указатель) члена другого класса.

• Когда вам требуется имя или вызов члена С. Например, когда вы вызываете функцию-член этого класса.

Не будем рассматривать в этой книге тривиальные случаи циклических зависимостей, которые приводят к ошибкам компиляции — думаем, вы успешно справитесь с ними, воспользовавшись многими хорошими советами, имеющимися в литературе и рекомендации 1. Мы же обратимся к циклическим зависимостям, которые остаются в компилируемом коде, и посмотрим, как они влияют на его качество и какие действия следует предпринять, чтобы избежать их.

В общем случае зависимости и их циклы следует рассматривать на уровне модулей. Модуль представляет собой образующий единое целое набор совместно опубликованных классов и функций (см. рекомендацию 5). Циклическая зависимость в простейшем виде представляет собой два класса, непосредственно зависящих друг от друга

class Child; // Устранение циклической зависимости

class Parent { // ...

 Child* myChild_;

};

// возможно, в другом заголовочном файле

class Child { // ...

 Parent* myParent_;

};

Перейти на страницу:

Все книги серии C++ In-Depth

Стандарты программирования на С++
Стандарты программирования на С++

Эта книга поможет новичку стать профессионалом, так как в ней представлен сконцентрированный лучший опыт программистов на С++, обобщенный двумя экспертами мирового класса.Начинающий программист найдет в ней простые и понятные рекомендации для ежедневного использования, подкрепленные примерами их конкретного применения на практике.Опытные программисты найдут в ней советы и новые рекомендации, которые можно сразу же принять на вооружение. Программисты-профессионалы могут использовать эту книгу как основу для разработки собственных стандартов кодирования, как для себя лично, так и для группы, которой они руководят.Конечно, книга рассчитана в первую очередь на профессиональных программистов с глубокими знаниями языка, однако она будет полезна любому, кто захочет углубить свои знания в данной области.

Андрей Александреску , Герб Саттер

Программирование, программы, базы данных

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных