Глава 2 Организация кода

Глава 2

Организация кода

2.0. Введение

Возможно, что одной из причин популярности C++ является его способность одинаково хорошо подходить для маленьких, средних и больших проектов. Для небольшого прототипа или исследовательского проекта можно написать всего несколько классов, а при росте проекта и увеличении числа сотрудников C++ позволяет масштабировать приложение, разбив его на модули, различающиеся по степени своей независимости. Недостатком здесь является то, что вы должны потратить время на то, чтобы вручную выполнить реорганизацию (добавить пространства имен, реорганизовать физическое расположение заголовочных файлов и т.д.). Обычно это стоит того, так как при этом приложение становится модульным и позволяет отдельным людям сосредоточиться только на их локальной функциональной области.

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

Если вы еще не используете пространства имен, вы, возможно, по крайней мере, слышали о них и уже используете одно из них: пространство имен std, которое является пространством имен, содержащим стандартную библиотеку. Исходя из моего опыта, пространства имен используются не настолько часто, насколько следовало бы но это не потому, что они очень сложны или их использование требует больших усилии. Рецепт 2.3 объясняет, как с помощью пространств имен сделать код модульным.

Многие рецепты этой главы описывают методики, применяемые в заголовочных файлах. Так как здесь обсуждается несколько возможностей, каждая из которых относится к отдельной части заголовочного файла, я поместил во введение пример 2.1, который показывает, как выглядит типичный заголовочный файл, который использует все методики, описанные в этой главе.

Пример 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__

После написания заголовочного файла также вам будет нужен файл реализации, под которым я понимаю файл .cpp, содержащий не только объявления, но и определения. Файл реализации оказывается менее сложным, чем заголовочный файл, но ради полноты пример 2.2 содержит пример реализации файла, идущего в комплекте с заголовочным файлом из примера 2.1.

Пример 2.2. Файл реализации

#include "myclass.h"

namespace mylib {

 MyClass::refCount_ = 0; // статическое определение, рецепт 8.4

 MyClass::foo() { // реализация метода

  // ...

 };

}

Конечно, файлы реализации будут полны обдуманных, хорошо написанных комментариев, но ради простоты я оставляю этот вопрос за скобками.