Время компиляции при использовании раздельной модели может сократиться благодаря тому, что сканирование определений шаблонов производится реже, и потому, что раздельная модель уменьшает зависимости между модулями.
Имена функций, классов и данных, используемых в файле реализации шаблона, могут быть полностью скрыты от кода, использующего этот шаблон, что снижает возможность случайного совпадения имен. Кроме того, автор реализации шаблона может уделять меньше внимания случайным совпадениям с именами из исходных файлов, использующих шаблон
Теоретически при использовании раздельной модели поставщик может распространять реализации шаблонов в скомпилированном двоичном виде, находящемся где-то посередине между исходным кодом C++ и обычными объектными файлами.
Все три потенциальных преимущества раздельной модели спорны. Во-первых, хотя некоторые пользователи сообщали о сокращении времени компиляции, раздельная модель также может в некоторых случаях привести к его увеличению. В настоящее время данных для окончательных выводов недостаточно. Во-вторых, хотя раздельная модель снижает некоторые виды загрязнения символов, правила языка, необходимые для поддержки раздельной модели, и особенно идея двухэтапного поиска, усложняют способ написания кода шаблона — даже по сравнению с включающей моделью - и имеют несколько нежелательных последствий. В-третьих, все существующие реализации раздельной модели основаны на оболочке EDG, a EDG пока еще не предоставляет никаких возможностей для компиляции исходных файлов, содержащих реализации экспортируемых шаблонов, в двоичные файлы, которые могут поставляться вместо исходников.
В 2003 году имела место попытка удалить экспортируемые шаблоны из будущих версий стандарта С ++, но она провалилась. Следовательно, экспортируемые шаблоны являются постоянной частью языка С+ +, и вы должны научиться использовать их.
Рецепт 1.25.
Глава 2
Организация кода
2.0. Введение
Возможно, что одной из причин популярности C++ является его способность одинаково хорошо подходить для маленьких, средних и больших проектов. Для небольшого прототипа или исследовательского проекта можно написать всего несколько классов, а при росте проекта и увеличении числа сотрудников C ++ позволяет масштабировать приложение, разбив его на модули, различающиеся по степени своей независимости. Недостатком здесь является то, что вы должны потратить время на то, чтобы вручную выполнить реорганизацию (добавить пространства имен, реорганизовать физическое расположение заголовочных файлов и т.д.). Обычно это стоит того, так как при этом приложение становится модульным и позволяет отдельным людям сосредоточиться только на их локальной функциональной области.
Количество необходимого ручного труда обратно пропорционально количеству времени, потраченному на первоначальную разработку модульности. Начните с нескольких хороших методик достижения модульности, и ваш код будет масштабируемым.
Если вы еще не используете пространства имен, вы, возможно, по крайней мере, слышали о них и уже используете одно из них: пространство имен std
, которое является пространством имен, содержащим стандартную библиотеку. Исходя из моего опыта, пространства имен используются не настолько часто, насколько следовало бы но это не потому, что они очень сложны или их использование требует больших усилии. Рецепт 2.3 объясняет, как с помощью пространств имен сделать код модульным.
Многие рецепты этой главы описывают методики, применяемые в заголовочных файлах. Так как здесь обсуждается несколько возможностей, каждая из которых относится к отдельной части заголовочного файла, я поместил во введение пример 2.1, который показывает, как выглядит типичный заголовочный файл, который использует все методики, описанные в этой главе.
#ifndef MYCLASS_H__ // защита #include, рецепт 2.0
#define MYCLASS_H__
#include <string>
namespace mylib { // пространства имен, рецепт 2.3
class AnotherClass; // предварительное объявление класса, рецепт 2.2
class Logger;
extern Logger* gpLogger; // объявление внешнего хранилища, рецепт 2.1
class MyClass {
public:
std::string getVal() const;
// ...
private:
static int refCount_;
std::string val_;
};
}
// Встраиваемые определения, рецепт 2.4
inline std::string MyClass::getVal() const {
return(val_);
}
#include 'myclass.inl'
} // namespace
#endif // MYCLASS_H__
После написания заголовочного файла также вам будет нужен файл
#include 'myclass.h'
namespace mylib {
MyClass::refCount_ = 0; // статическое определение, рецепт 8.4