Принятый ответ объясняет это для виртуальных частных функций, но он отвечает только на один конкретный аспект вопроса, который значительно более ограничен, чем то, что задавал ОП. Итак, нам нужно перефразировать: почему мы должны объявлять не виртуальные частные функции в заголовках?
Другой ответ вызывает тот факт, что классы должны быть объявлены в одном блоке - после чего они запечатаны и не могут быть добавлены. Это то, что вы будете делать, опуская объявление частного метода в заголовке, а затем пытаясь определить его в другом месте. Хороший вопрос. Почему некоторые пользователи этого класса должны иметь возможность расширять его так, чтобы другие пользователи не могли наблюдать? Частные методы являются его частью и не исключаются из этого. Но затем вы спрашиваете, почему они включены, и это кажется немного тавтологическим. Почему классные пользователи должны знать о них? Если бы они не были видны, пользователи не могли бы добавить ни одного, и эй Presto.
Итак, я хотел бы дать ответ, который вместо того, чтобы просто включать частные методы по умолчанию, дает определенные моменты в пользу того, чтобы они были видны пользователям. Механистическая причина для не-виртуальных частных функций, требующих публичного объявления, дана в GotW # 100 Херба Саттера об идиоме Pimpl в качестве части ее обоснования. Я не буду рассказывать о Пимпле здесь, так как уверен, что мы все знаем об этом. Но вот соответствующий бит:
В C ++, когда что-либо в определении класса заголовочного файла изменяется, все пользователи этого класса должны быть перекомпилированы - даже если единственным изменением были члены частного класса, к которым пользователи класса не могут даже получить доступ. Это связано с тем, что модель сборки C ++ основана на текстовом включении, а C ++ предполагает, что вызывающие стороны знают две основные вещи о классе, на который могут влиять частные члены:
- Размер и макет : [членов и виртуальных функций - не требует пояснений и отлично подходит для производительности, но не потому, что мы здесь]
- Функции : вызывающий код должен иметь возможность разрешать вызовы функций-членов класса, включая недоступные частные функции, которые перегружаются несобственными функциями - если частная функция лучше подходит, вызывающий код не сможет скомпилироваться. (C ++ принял преднамеренное проектное решение, чтобы выполнить разрешение перегрузки перед проверкой доступности по соображениям безопасности. Например, считалось, что изменение доступности функции с частного на общедоступное не должно изменить значение легального вызывающего кода.)
Саттер, конечно, является чрезвычайно надежным источником в качестве члена Комитета, поэтому он знает «обдуманное дизайнерское решение», когда видит его. И идея требовать публичного объявления частных методов как способа избежать измененной семантики или случайно нарушенной доступности позже, вероятно, является наиболее убедительным обоснованием. К счастью, все это казалось довольно бессмысленным до сих пор!