Закрытые переменные - это способ скрыть сложность и детали реализации для пользователя класса. Это довольно приятная особенность. Но я не понимаю, почему в C ++ нам нужно поместить их в заголовок класса. Я вижу два досадных недостатка в этом:
- Загромождает заголовок от пользователя
- Вызывает перекомпиляцию всех клиентских библиотек при изменении внутренних компонентов
Есть ли концептуальная причина этого требования? Это только для облегчения работы с компилятором?
struct foo{};
) не разрешен, но есть предварительные объявления (struct foo;
).Ответы:
Это происходит потому, что компилятор C ++ должен знать фактический размер класса, чтобы выделять нужный объем памяти при создании экземпляра. И размер включает в себя все члены, а также частные.
Один из способов избежать этого - использовать идиому Пимпл , объясненную Хербом Саттером в его «Гуру недели», серии № 24 и № 28 .
Обновить
Действительно, это (или, в более общем смысле, различие между заголовочным и исходным файлами и
#include
s) является основным препятствием в C ++, унаследованном от C. В те времена, когда создавалсяC ++C, еще не было опыта крупномасштабной разработки программного обеспечения, где начинает вызывать реальные проблемы. Уроки, извлеченные с тех пор, были учтены разработчиками более новых языков, но C ++ связан с требованиями обратной совместимости, что делает действительно трудным решение такой фундаментальной проблемы в языке.источник
private
более современно.Определение класса должно быть достаточным для того, чтобы компилятор создал идентичный макет в памяти, где бы вы ни использовали объект класса. Например, учитывая что-то вроде:
Компилятор обычно имеет
a
смещение 0 иb
смещение4
. Если компилятор видит это просто:Было бы «думать», что
b
должно быть смещение 0 вместо смещения 4. Когда код, использующий это определение, назначенb
, код, использующий первое определение, будетa
видоизменяться, и наоборот.Обычный способ минимизировать последствия внесения изменений в приватные части класса обычно называют идиомой pimpl (о которой, я уверен, Google может дать много информации).
источник
Скорее всего, есть несколько причин. Хотя закрытые члены не могут быть доступны большинству других классов, они все же могут быть доступны для классов друзей. Так что, по крайней мере, в этом случае они могут понадобиться в заголовке, чтобы класс друга мог видеть, что они существуют.
Перекомпиляция зависимых файлов может зависеть от вашей структуры включения. Включение файлов .h в файл .cpp вместо другого заголовка может в некоторых случаях предотвратить длинные цепочки перекомпиляций.
источник