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