Мне сказали не включать слишком много классов в .header, если я могу избежать этого, и вместо этого включать их в .cpp. Для этого они сказали, чтобы я создавал классы прототипов, такие как:
class abc;
вместо:
include "abc.h"
Но это на всякий случай, если класс abc не используется в качестве атрибута или возвращаемого значения. Если это параметр, я могу использовать прототип … Почему это?
Кроме того, почему так плохо включать так много заголовков в файл .h?
Спасибо
Если это параметр, я могу использовать прототип … Почему это?
Вы можете использовать предварительное объявление всякий раз, когда вам не нужен доступ к внутренней структуре объявленного класса, например, когда вы объявляете указатель, ссылку или передаете его в качестве параметра. Вы не можете использовать прямое объявление для наследования класса, вызова любой из его функций-членов или доступа к его членам, или для объявления членов не указательного / ссылочного типа: это потому, что внутренняя структура класса должна быть известна компилятору, чтобы сделать любое из вышеперечисленного.
почему так плохо включать столько заголовков в файл .h?
Это не всегда «плохо» само по себе, но со многими компиляторами это может замедлить процесс компиляции, поэтому типично минимизировать ваши включения. Современные компиляторы имеют полезные функции (такие как предварительно скомпилированные заголовки), чтобы минимизировать влияние, поэтому использование предварительных объявлений, где вы можете, становится более эстетичным выбором, чем практическим вопросом.
Когда вы объявляете класс вперед:
class abc;
это становится неполный тип, и есть только определенные вещи, которые вы можете сделать с неполным типом. Например, все, что требует знания членов класса или даже знания его размера, потребует полной декларации.
Что касается включения заголовков из других заголовков, я могу привести два аргумента против:
Первый может быть или не быть релевантным в зависимости от размера вашего проекта, вашего компилятора, аппаратного обеспечения и т. Д. Второй также сомнительный, поскольку он действительно не уменьшает зависимости между классами.
Одна ситуация, когда ты иметь использовать прямое объявление, когда у вас есть циклическая зависимость между двумя классами, определенными в разных заголовках.
class abc;
Когда вы объявляете тип вперед, компилятор обрабатывает его как Тип дохода и он не имеет никакой информации о расположении / составе памяти этого типа. Таким образом, вы не можете попросить компилятор выполнить какую-либо операцию, которая требует, чтобы он знал эту информацию.
С Incomplete type вы не можете:
Но с незавершенным типом вы можете:
почему так плохо включать столько заголовков в файл .h?
Это плохо, потому что:
Плохо включать много заголовков, так как если вы измените один из них, вам также придется скомпилировать файл, что может показаться проблемой, но для больших программ компиляция + компоновка может занять много времени (иногда часов)
Все, что нужно знать компилятору — это имя, а не композиция, пока ему не понадобится сгенерировать код.
Таким образом, предварительное объявление — это путь, так как он не требует загрузки и анализа.
Кстати, помогает, что make-файл не должен начинать перекомпиляцию.