Почему вы хотите поместить класс в файл реализации?
При просмотре некоторого кода я столкнулся с следующим:
.h файл
class ExampleClass
{
public:
// methods, etc
private:
class AnotherExampleClass* ptrToClass;
}
.cpp file
class AnotherExampleClass
{
// methods, etc
}
// AnotherExampleClass and ExampleClass implemented
Это шаблон или что-то полезное при работе на С++? Поскольку класс не разбит на другой файл, способствует ли этот рабочий поток более быстрое время компиляции?
или это просто стиль этого разработчика?
Ответы
Ответ 1
Это по-разному известно как pImpl Idiom, технику Cheshire cat или компиляционный брандмауэр.
Преимущества:
- Изменение переменных частного члена класса не требует перекомпиляции классов, которые зависят от него, тем самым ускоряя время, и FragileBinaryInterfaceProblem уменьшается.
- В заголовочном файле не требуется #include классы, которые используются "по значению" в частных переменных-членах, поэтому время компиляции выполняется быстрее.
- Это похоже на то, как SmallTalk автоматически обрабатывает классы... более чистую инкапсуляцию.
Недостатки:
- Больше работы для разработчика.
- Не работает для "защищенных" членов, где требуется доступ по подклассам.
- Несколько сложнее прочитать код, поскольку некоторая информация больше не находится в файле заголовка.
- Производительность во время выполнения слегка скомпрометирована из-за указателя указателя, особенно если вызовы функций виртуальны (прогнозирование ветвлений для непрямых ветвей вообще невелико).
Книги "Исключительные С++" Herb Sutter также полезны для правильного использования этой техники.
Ответ 2
Наиболее распространенным примером может быть использование шаблона PIMPL или аналогичных методов. Тем не менее, есть и другие виды использования. Как правило, различие .hpp/.cpp в С++ скорее (или, по крайней мере, может быть) является одним из публичного интерфейса или частной реализации. Если тип используется только как часть реализации, то это хорошая причина не экспортировать его в файл заголовка.
Ответ 3
Помимо возможной реализации идиомы PIMPL, вот еще две возможные причины:
Объекты в С++ не могут изменять указатель this
. Как следствие, они не могут изменять тип в среднем использовании. Тем не менее, ptrToClass
может измениться, разрешив реализацию самому delete
и заменив себя другим экземпляром другого подкласса AnotherExampleClass
.
Если реализация AnotherExampleClass
зависит от некоторых параметров шаблона, но интерфейс ExampleClass
не работает, можно использовать шаблон, полученный из AnotherExampleClass
, чтобы обеспечить реализацию. Это скрывает часть необходимой, но внутренней информации типа от пользователя класса интерфейса.