ІМХО, існуючі відповіді погано спрацьовують питання "чому" цього - занадто багато зосереджуючись на повторенні того, яка поведінка є дійсною. "модифікатори доступу працюють на рівні класу, а не на рівні об'єкта." - так, але чому?
Основною концепцією тут є те, що саме програміст (и) розробляє, пише та підтримує клас, який (як очікується) зрозуміє бажану інкапсуляцію ОО та наділений повноваженнями координувати її реалізацію. Отже, якщо ви пишете class X, ви кодуєте не просто те, як окремий X xоб’єкт може використовуватися кодом з доступом до нього, а й те, як:
- похідні класи можуть взаємодіяти з ним (за вибором - чисто віртуальні функції та / або захищений доступ), і
- окремі
Xоб'єкти співпрацюють, щоб забезпечити передбачувану поведінку, одночасно дотримуючись пост-умов та інваріантів вашого дизайну.
Це не тільки конструктор копіювання - дуже багато операцій можуть включати два або більше екземплярів вашого класу: якщо ви порівнюєте, додаєте / множите / ділите, копіюєте, конструюєте, клонуєте, присвоюєте тощо, то часто трапляється так, що ви або просто повинен мати доступ до приватних та / або захищених даних в іншому об'єкті, або хотіти, щоб він дозволяв простішу, швидшу або, як правило, кращу реалізацію функції.
Зокрема, ці операції можуть захотіти скористатися привілейованим доступом, щоб робити такі речі:
- (конструктори копіювання) використовують приватний член об'єкта "rhs" (праворуч) у списку ініціалізатора, так що змінна члена сама створюється за копією замість побудованої за замовчуванням (якщо навіть легальна), а потім теж призначається (знову ж якщо законно)
- спільний доступ до ресурсів - дескриптори файлів, сегменти спільної пам'яті,
shared_ptrs для посилань на дані тощо.
- взяти у власність речі, наприклад,
auto_ptr<>" перенести " право власності на об'єкт, що будується
- копіювати приватний "кеш", калібрування або члени стану, необхідні для побудови нового об'єкта в оптимально зручному стані без необхідності їх регенерації з нуля
- копіювати / отримувати інформацію про діагностику / трасування, що зберігається в об'єкті, який копіюється, інакше не доступний через загальнодоступні API, але може бути використаний якимсь пізнішим об'єктом виключення або реєстрацією (наприклад, щось про час / обставини, коли "оригінальний" екземпляр, створений без копіювання був побудований)
- виконувати більш ефективну копію деяких даних: наприклад, об’єкти можуть мати, наприклад,
unordered_mapчлена, але загальнодоступні лише викриття begin()та end()ітератори - з прямим доступом до size()вас може reserveбути швидшим копіюванням; ще гірше , якщо вони тільки викрити at()і insert()в іншому випадку throw....
- копіювати посилання назад до батьківських / координаційних / керуючих об’єктів, які можуть бути невідомими або лише для запису для клієнтського коду