ИМХО, существующие ответы плохо справляются с объяснением «почему» этого - слишком много внимания уделяется повторению того, какое поведение является допустимым. «Модификаторы доступа работают на уровне класса, а не на уровне объекта». - Да, но почему?
Общая концепция здесь заключается в том, что программисты, проектирующие, пишущие и поддерживающие класс, должны понимать желаемую инкапсуляцию объектно-ориентированного программирования и уполномочены координировать ее реализацию. Итак, если вы пишете class X
, вы кодируете не только то, как отдельный X x
объект может использоваться кодом с доступом к нему, но и то, как:
- производные классы могут взаимодействовать с ним (через необязательно чистые виртуальные функции и / или защищенный доступ) и
- отдельные
X
объекты взаимодействуют, чтобы обеспечить предполагаемое поведение, соблюдая пост-условия и инварианты вашего дизайна.
Это не просто конструктор копирования - очень многие операции могут включать два или более экземпляра вашего класса: если вы сравниваете, добавляете / умножаете / делите, копируете, клонируете, присваиваете и т. Д., То часто бывает, что вы либо просто должен иметь доступ к частным и / или защищенным данным в другом объекте, либо он должен обеспечивать более простую, быструю или в целом лучшую реализацию функций.
В частности, эти операции могут захотеть воспользоваться привилегированным доступом для выполнения таких действий, как:
- (конструкторы копирования) используют закрытый член объекта "rhs" (правая сторона) в списке инициализаторов, так что переменная-член сама создается копией, а не создается по умолчанию (если даже допустимо), а затем назначается тоже (опять же, если законно)
- общие ресурсы - дескрипторы файлов, сегменты разделяемой памяти,
shared_ptr
ссылки на данные и т. д.
- взять на себя ответственность за вещи, например
auto_ptr<>
"перемещает" право собственности на строящийся объект
- копировать частный «кэш», калибровку или члены состояния, необходимые для создания нового объекта в оптимально пригодном для использования состоянии без необходимости их регенерации с нуля
- копировать / получать доступ к диагностической / отслеживаемой информации, хранящейся в копируемом объекте, которая иначе недоступна через общедоступные API, но может использоваться некоторым более поздним объектом исключения или журналированием (например, что-то о времени / обстоятельствах, когда "исходный" не созданный копией экземпляр был построен)
- выполнить более эффективную копию некоторых данных: например , объекты могут иметь , например , с
unordered_map
членом , но публично только разоблачить begin()
и end()
итераторы - с прямым доступом к size()
вам могли reserve
емкость для быстрого копирования; еще хуже , если они только разоблачить at()
и insert()
в противном случае throw
....
- копировать ссылки обратно на родительские / координационные / управляющие объекты, которые могут быть неизвестными или доступными только для записи для клиентского кода