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