Подтвердить что ты не робот

Почему я могу получить доступ к приватным переменным в конструкторе копирования?

Я узнал, что я никогда не могу получить доступ к частной переменной, только с функцией get в классе. Но почему я могу получить доступ к нему в конструкторе копирования?

Пример:

Field::Field(const Field& f)
{
  pFirst = new T[f.capacity()];

  pLast = pFirst + (f.pLast - f.pFirst);
  pEnd  = pFirst + (f.pEnd - f.pFirst);
  std::copy(f.pFirst, f.pLast, pFirst);
}

Мое выражение:

private:
  T *pFirst,*pLast,*pEnd;
4b9b3361

Ответ 1

ИМХО, существующие ответы дают плохую работу, объясняющую "Почему" этого - слишком много внимания, повторяя, какое поведение действительно. "Модификаторы доступа работают на уровне класса, а не на уровне объекта". - да, но почему?

Общая концепция здесь заключается в том, что программист (программисты) проектирует, пишет и поддерживает класс, который (как ожидается) понимает желаемую инкапсуляцию OO и уполномочен координировать ее реализацию. Итак, если вы пишете class X, вы кодируете не только то, как отдельный объект X x может использоваться кодом с доступом к нему, но также как:

  • производные классы могут взаимодействовать с ним (через необязательно чистые виртуальные функции и/или защищенный доступ) и
  • Различные X объекты сотрудничают, чтобы обеспечить предполагаемое поведение, соблюдая приложенные условия и инварианты от вашего дизайна.

Это не просто конструктор копий - большое количество операций может включать в себя два или более экземпляра вашего класса: если вы сравниваете, добавляете/умножаете/деляете, копируете, клонируете, присваиваете и т.д., то часто случай, когда вы либо просто должны иметь доступ к закрытым и/или защищенным данным в другом объекте, либо хотите, чтобы он позволял выполнять более быструю или более быструю реализацию функции.

В частности, эти операции могут использовать привилегированный доступ, чтобы делать такие вещи, как:

  • (конструкторы копирования) используют частный член объекта "rhs" (правая сторона) в списке инициализации, так что переменная-член сама построена по-копированию вместо построенной по умолчанию (если она даже законна), а затем назначается слишком (опять же, если это законно)
  • совместно использовать ресурсы - файлы, сегменты разделяемой памяти, shared_ptr для ссылки на данные и т.д.
  • взять на себя ответственность за вещи, например. auto_ptr<> "перемещает" собственность на объект, находящийся в стадии разработки.
  • копировать частные "кешированные", калибровочные или государственные элементы, необходимые для создания нового объекта в оптимально используемом состоянии без необходимости регенерировать их с нуля
  • информация о копировании/доступе/информация о трассировке, хранящаяся в копируемом объекте, который иным образом не доступен через общедоступные API, но может использоваться каким-либо более поздним объектом исключения или протоколированием (например, что-то о времени/обстоятельствах, когда "оригинальная" копия построенный экземпляр)
  • выполнить более эффективную копию некоторых данных: например, объекты могут иметь, например, a unordered_map, но публично выставлять begin() и end() итераторы - с прямым доступом к size() вы могли бы reserve емкость для более быстрого копирования; хуже, если они только выставляют at() и insert() и в противном случае throw....
  • копировать ссылки обратно на родительские/координационные/управляющие объекты, которые могут быть неизвестны или только для записи для кода клиента.

Ответ 2

Модификаторы доступа работают на уровне класса, а не на уровне уровня.

То есть, два объекта одного и того же класса могут получить доступ к личным данным других.

Почему:

В первую очередь из-за эффективности. Было бы непроизводительным временем выполнения во время выполнения проверки, если this == other каждый раз, когда вы получаете доступ к other.x, который вам нужен, если модификаторы доступа работают на уровне объекта.

Это также семантически логично, если вы думаете об этом с точки зрения охвата: "Насколько важна часть кода, которую нужно учитывать при изменении частной переменной?" - Вам нужно учесть код всего класса, и это ортогонально, какие объекты существуют во время выполнения.

И это невероятно удобно при написании конструкторов копий и операторов присваивания.

Ответ 3

Вы можете получить доступ к закрытым членам класса из класса, даже к другому экземпляру.

Ответ 4

Чтобы понять ответ, я хотел бы напомнить вам несколько концепций.

  • Независимо от того, сколько объектов вы создаете, в памяти для этого класса имеется только одна копия одной функции. Это означает, что функции создаются только один раз. Однако переменные являются отдельными для каждого экземпляра класса.
  • this указатель передается каждой функции при вызове.

Теперь из-за указателя this функция может находить переменные этого конкретного экземпляра. независимо от того, является ли он публичным. он может быть доступен внутри этой функции. Теперь, если мы передаем указатель на другой объект того же класса. используя этот второй указатель, мы сможем получить доступ к закрытым членам.

Надеюсь, это ответит на ваш вопрос.

Ответ 5

Конструктор копирования - это функция-член класса и как таковая имеет доступ к элементам данных класса, даже те, которые объявлены как 'private'.