Спецификаторы доступа C++

Я просто хочу удостовериться, что понял идею публичного и частного права.

Что касается спецификатора частного доступа, означает ли это:

  • Только доступен внутри класса
  • Невозможно получить доступ из объекта класса, если нет общедоступных методов класса, которые можно использовать для доступа к ним (Могут ли другие объекты использовать эти общедоступные функции?)
  • Ни один другой объект не может получить к ним доступ

И для публики:

  • Доступ из объекта класса
  • Доступ из любого другого объекта

Это правильно?


person Simplicity    schedule 07.02.2011    source источник
comment
есть третий общий уровень: protected. это работает как private, за исключением того, что подклассы также могут получать доступ к защищенным методам/данным. конечно, компилятор также проверит, что ваш доступ соответствует интерфейсу. private блокирует доступ подклассов к частному интерфейсу базового класса.   -  person justin    schedule 07.02.2011
comment
Мне кажется, вы путаете понятия. Что является объектом класса? В этом контексте класс и объект класса в основном совпадают.   -  person Gorpik    schedule 07.02.2011


Ответы (5)


Я думаю, что есть проблема словарного запаса, чтобы начать с.

В C++ (и большинстве языков) class равно type. Вы можете думать об этом как о плане, чтобы действительно что-то построить.

  • он описывает атрибуты, которые хранятся
  • он описывает методы работы с этими атрибутами
  • он описывает применяемые ограничения: это «доступность»

object создается путем фактического создания экземпляра класса, то есть построения того, что описано в схеме. Это более или менее набор атрибутов. У вас может быть несколько объектов одного класса, как у вас может быть несколько домов из одного чертежа: обратите внимание, что их физическое расположение отличается по понятным причинам :)

Теперь о доступности. Существует 3 типичных уровня доступности: public, protected и private.

  • public, как и ожидалось, означает, что всем предоставляется доступ либо к атрибутам, либо к методам.
  • protected несколько менее тривиален. Это означает, что только объект или его дочерние элементы могут получить доступ к атрибутам (плохая идея*) или методам. (Плюс, в С++, friends)
  • private означает, что только объекты этого класса (а не их дочерние элементы) могут получить доступ к атрибутам или методам (плюс, в C++, friends)

Примечание: независимо от уровня доступности объект имеет неограниченный доступ ко всем атрибутам и методам любого объекта того же класса.

(*) Несмотря на то, что это всплывает время от времени, использование атрибутов protected — плохая идея. Смысл инкапсуляции в том, чтобы скрыть детали не только ради них самих, но и потому, что точно контролируя, кто может получить доступ к данным, мы можем гарантировать, что класс поддерживает свои инварианты (простой пример, массив, где вы бы хранили размер отдельно, вам необходимо убедиться, что «размер» действительно всегда представляет количество элементов в массиве). Примечание. Это ограничение не применяется, когда вы можете запечатать иерархию, как, например, в C#.

person Matthieu M.    schedule 07.02.2011
comment
В вашей формулировке protected звучит более ограничительно, чем private для того же класса. Кроме того, что такое дочерние объекты объекта? - person juanchopanza; 25.08.2016
comment
@juanchopanza: дочерние элементы должны быть суперобъектами (в случае доступа производного экземпляра к атрибутам своего базового объекта). Если у вас есть лучшая формулировка, чтобы предложить, я полностью за это. - person Matthieu M.; 25.08.2016
comment
Может быть, s/object/type/ ? - person juanchopanza; 25.08.2016

private : к нему могут получить доступ только функции-члены и друзья класса.
public : доступ возможен в любом месте, где объект имеет область видимости.


Отвечая на вопросы -

частное:

  1. Да
  2. Да. (Могут ли другие объекты использовать эти общедоступные функции? Без классовых отношений один объект класса не может общаться с членами другого.)
  3. Друзья имеют доступ к закрытым членам класса. Итак, ответ зависит от того, есть у вашего класса друзья или нет.

общедоступно:

  1. Да
  2. Зависит от того, имеет ли объект иерархические отношения с классом члена, к которому вы пытаетесь получить доступ.
person Mahesh    schedule 07.02.2011
comment
В ООП полностью опущен очень важный спецификатор доступа — это, конечно, protected, который в основном работает как private, за исключением того, что подклассы объявляющего класса также имеют доступ к этим членам. - person pdinklag; 07.02.2011
comment
@pdinklag: на самом деле не очень важно. Определенно плохая идея для атрибутов, почти бесполезных для функций, которые можно использовать с конструкторами/назначениями/деструкторами в некоторых сценариях. - person Matthieu M.; 07.02.2011
comment
@Matthieu, далеко не бесполезный для функций. Набор чисто виртуальных защищенных функций часто используется для определения интерфейса, который должны реализовать производные классы. Затем базовый класс использует этот интерфейс для выполнения реальных задач. QIODevice::readData() — хороший тому пример. - person Sergei Tachenov; 07.02.2011
comment
@Сергей: я не имею в виду, что его нельзя использовать, но между protected и public мало различий, в лучшем случае, насколько я понимаю, это функция документации. Демонстрация: struct B: QIODevice { x readDataHack() { return readData(); } };, теперь readData, во всех смыслах и целях, public. Обратите внимание, что это не относится к конструкторам/деструкторам и т.п. - person Matthieu M.; 07.02.2011
comment
@Matthieu, ну, я думаю, можно злоупотреблять чем угодно, но это не делает его бесполезным, потому что теперь вы должны намеренно сделать что-то вроде этого, а если бы это было публично с самого начала, это не предотвратило бы даже случайного использование его вне урока. Кто-то может просто использовать readData() вместо правильного метода read(). Когда readData() защищен, вместо этого он увидит ошибку, внимательно прочитает документы и на этот раз использует правильный метод. - person Sergei Tachenov; 07.02.2011
comment
@Сергей: я согласен, это аннотация, проверенная компилятором, а не простой комментарий. Но private здесь было бы полезнее (по крайней мере, для чистого виртуального). protected можно использовать, когда вы предоставляете реализацию, потому что таким образом, даже переопределяя, можно вызвать исходную реализацию в переопределении. - person Matthieu M.; 07.02.2011
comment
@Matthieu, чистые виртуальные функции тоже могут иметь реализацию. Однако не уверен, что это можно считать хорошей практикой. - person Sergei Tachenov; 07.02.2011
comment
@Сергей: да, я использовал его несколько раз, когда можно указать значимое значение по умолчанию, но вы хотите, чтобы разработчик сделал сознательный выбор. В данном случае, очевидно, private никуда не годится. - person Matthieu M.; 07.02.2011

К закрытым членам могут обращаться только функции-члены и статические функции того же класса, а также друзья этого класса. Неважно, на каком объекте вызывается эта функция. Итак, дело

class Foo
{
  private:
    void bar() {}
  public:
    void baz(Foo& var)
    {
      var.bar();
    }
}

совершенно законно.

person Oswald    schedule 07.02.2011

Это кажется правильным. К членам данных и функциям, помеченным как общедоступные, любой может получить доступ из любого места. Члены данных и функции, помеченные как частные, доступны только классу и его друзьям. Однако функция-член класса может получить доступ к данным с любым спецификатором доступа, поэтому общедоступная функция может читать и записывать частные члены данных (это повсеместно используется в ООП).

person templatetypedef    schedule 07.02.2011

В С++ данные и fn инкапсулируются как 1 блок. Мы начинаем программу с написания директив препроцессора. Затем следует объявление класса. Затем следует объявление функции (fn), где мы также указываем модификатор доступа (public, private или protected)

и, наконец, основная () программа.

Если мы объявим fn Private: данные внутри объекта класса доступны только через fn, определенный в нем (объект, который имеет данные и частный fn)

Публичный: данные могут быть доступны любому fn

Защищенный: аналогичен частному, однако к данным также могут обращаться подклассы, которые наследуют свойства другого класса.

Например, если класс A наследуется от класса B, то A является подклассом B.

person Jayraj Srikriti Naidu    schedule 25.08.2016
comment
Надеюсь, вы найдете это полезным. - person Jayraj Srikriti Naidu; 25.08.2016