Должны ли вы когда-либо использовать защищенные переменные-члены?

Стоит ли вам когда-либо использовать защищенные 9X_protected переменные-члены? Каковы преимущества и 9X_object-oriented какие проблемы это может вызвать?

105
0
10
Общее количество ответов: 10

Ответ #1

Ответ на вопрос: Должны ли вы когда-либо использовать защищенные переменные-члены?

Стоит ли вам когда-либо использовать защищенные 9X_object-oriented-modeling переменные-члены?

Зависит от того, насколько 9X_object-oriented-modeling вы разборчивы в сокрытии состояния.

  • Если вы не хотите утечки внутреннего состояния, то объявление всех ваших переменных-членов закрытыми - это путь.
  • Если вас не волнует, что подклассы могут получить доступ к внутреннему состоянию, тогда protected достаточно.

Если 9X_object-oriented появится разработчик и создаст подклассы 9X_oo-design вашего класса, они могут все испортить, потому 9X_protected что не понимают его полностью. С закрытыми 9X_oop членами, кроме общедоступного интерфейса, они 9X_oo не могут видеть конкретные детали реализации 9X_oo-design того, как что-то делается, что дает вам 9X_oo возможность изменить его позже.

81
4

  • @Black Очевидно, что Allain означал «они не могут ** получить доступ **» к этим членам и, следовательно, не могут создават ...

Ответ #2

Ответ на вопрос: Должны ли вы когда-либо использовать защищенные переменные-члены?

Обычно, если что-то намеренно не считается 9X_oops публичным, я делаю это приватным.

Если возникает 9X_ood ситуация, когда мне нужен доступ к этой 9X_ood частной переменной или методу из производного 9X_oops класса, я меняю его с частного на защищенный.

Это 9X_oop почти никогда не происходит — я вообще не 9X_oo-design фанат наследования, так как это не особенно 9X_object-oriented-modeling хороший способ моделирования большинства 9X_object-oriented ситуаций. В любом случае, продолжайте, не 9X_oops беспокойтесь.

Я бы сказал, что это нормально 9X_ood (и, возможно, это лучший способ) для большинства 9X_protected разработчиков.

Дело в том, что если какой-то другой разработчик 9X_object-oriented появится через год и решит, что ему нужен 9X_ood доступ к вашей закрытой переменной-члену, он 9X_ood просто отредактирует код, изменит его на 9X_protected защищенный и продолжит свою работу. бизнес.

Единственными 9X_ood реальными исключениями из этого являются 9X_protected случаи, когда вы занимаетесь доставкой двоичных 9X_protected dll в форме черного ящика третьим сторонам. В 9X_oop основном это Microsoft, эти поставщики «Custom 9X_oo-design DataGrid Control» и, возможно, несколько 9X_object-oriented других крупных приложений, которые поставляются 9X_ood с библиотеками расширяемости. Если вы не 9X_object-orientation относитесь к этой категории, не стоит тратить 9X_oops время/усилия, чтобы беспокоиться о таких 9X_oo вещах.

37
0

Ответ #3

Ответ на вопрос: Должны ли вы когда-либо использовать защищенные переменные-члены?

В настоящее время считается, что они вызывают 9X_object-orientation чрезмерную связь между производными классами 9X_oop и их базами.

У них нет особого преимущества 9X_oo перед защищенными методами/свойствами (когда-то 9X_oo-design они могли иметь небольшое преимущество в 9X_object-oriented производительности), и они также больше 9X_oop использовались в эпоху, когда было в моде 9X_oo-design очень глубокое наследование, чего сейчас 9X_oop нет. .

33
3

  • Разве «отсутствие особого преимущества перед защищенными методами / свойствами» не должно быть «особым преимуществом перед * частными ...

Ответ #4

Ответ на вопрос: Должны ли вы когда-либо использовать защищенные переменные-члены?

Ключевая проблема для меня заключается в 9X_object-orientation том, что после того, как вы сделаете переменную 9X_object-oriented-design защищенной, вы не сможете разрешить никакому 9X_protected методу в вашем классе полагаться на то, что его значение 9X_oop находится в пределах диапазона, потому что 9X_protected подкласс всегда может разместить его вне 9X_oo диапазона.

Например, если у меня есть класс, который 9X_object-oriented определяет ширину и высоту визуализируемого 9X_ood объекта, и я делаю эти переменные защищенными, тогда 9X_oop я не могу делать никаких предположений относительно 9X_oops (например) соотношения сторон.

Крайне важно, я 9X_protected не могу никогда делать эти предположения в любой 9X_object-orientation момент с момента выпуска этого кода в виде 9X_oop библиотеки, поскольку даже если я обновлю 9X_oo-design свои сеттеры для поддержания соотношения 9X_object-orientation сторон, у меня нет гарантии, что переменные 9X_protected устанавливаются через сеттеры или доступны 9X_oo через геттеры в существующем коде.

Ни один 9X_object-orientation из подклассов моего класса не может предоставить 9X_oops эту гарантию, поскольку они также не могут 9X_oops обеспечить соблюдение значений переменных, даже если это весь смысл их подкласса.

В 9X_oo-design качестве примера:

  • У меня есть класс прямоугольника, ширина и высота которого хранятся как защищенные переменные.
  • Очевидным подклассом (в моем контексте) является класс DisplayedRectangle, единственное отличие которого состоит в том, что я ограничиваю ширину и высоту допустимыми значениями для графического отображения.
  • Но сейчас это невозможно, поскольку мой класс DisplayedRectangle не может по-настоящему ограничивать эти значения, поскольку любой его подкласс может напрямую переопределять значения, но при этом рассматривается как DisplayedRectangle. .

Ограничивая переменные 9X_oops частными, я могу затем обеспечить желаемое 9X_oop поведение через сеттеры или геттеры.

10
0

Ответ #5

Ответ на вопрос: Должны ли вы когда-либо использовать защищенные переменные-члены?

В общем, я бы сохранил ваши защищенные переменные-члены 9X_oop в редких случаях, когда вы полностью контролируете 9X_oo код, который их также использует. Если вы 9X_object-oriented-design создаете публичный API, я бы сказал никогда. Ниже 9X_oo мы будем называть переменную-член «свойством» объекта.

Вот 9X_object-oriented что ваш суперкласс не может делать после того, как 9X_oop переменная-член будет защищена, а не закрыта 9X_object-orientation с аксессорами:

  1. лениво создайте значение на 9X_ood лету, когда свойство читается. Если вы добавите 9X_oo защищенный метод получения, вы можете лениво 9X_object-oriented-design создать значение и передать его обратно.

  2. знать, когда 9X_protected свойство было изменено или удалено. Это 9X_object-oriented-design может привести к ошибкам, когда суперкласс 9X_oop делает предположения о состоянии этой переменной. Создание 9X_object-oriented защищенного метода установки для переменной 9X_object-oriented-modeling сохраняет этот контроль.

  3. Установите точку 9X_object-oriented останова или добавьте вывод отладки при 9X_ood чтении или записи переменной.

  4. Переименуйте 9X_object-oriented-modeling эту переменную-член, не просматривая весь 9X_object-oriented-modeling код, который может ее использовать.

В целом, я 9X_object-oriented думаю, что это был бы редкий случай, когда 9X_oo я бы рекомендовал создать защищенную переменную-член. Лучше 9X_object-orientation потратить несколько минут на раскрытие свойства 9X_oops через геттеры / сеттеры, чем спустя несколько 9X_oo часов, отслеживая ошибку в каком-либо другом 9X_oops коде, который изменил защищенную переменную. Более 9X_object-oriented-design того, вы застрахованы от добавления будущих 9X_object-oriented-modeling функций (например, отложенной загрузки) без 9X_object-orientation нарушения зависимого кода. Сделать это позже 9X_oo-design труднее, чем сейчас.

9
0

Ответ #6

Ответ на вопрос: Должны ли вы когда-либо использовать защищенные переменные-члены?

На уровне дизайна может быть уместно использовать 9X_oo защищенное свойство, но для реализации я 9X_oo-design не вижу преимуществ в сопоставлении его 9X_oops с защищенной переменной-членом, а не с методами 9X_protected доступа / мутатора.

Защищенные переменные-члены 9X_oo имеют существенные недостатки, поскольку 9X_object-oriented-modeling они позволяют клиентскому коду (подклассу) получить 9X_oop доступ к внутреннему состоянию класса базового 9X_oo-design класса. Это мешает базовому классу эффективно 9X_ood поддерживать свои инварианты.

По той же причине 9X_oop защищенные переменные-члены также значительно 9X_oops затрудняют написание безопасного многопоточного 9X_oop кода, если только не гарантируется константа 9X_protected или не ограничивается одним потоком.

Методы 9X_oo доступа / мутатора предлагают значительно 9X_oops большую стабильность API и гибкость реализации 9X_object-oriented при обслуживании.

Кроме того, если вы сторонник 9X_object-orientation объектно-ориентированного подхода, объекты 9X_oo-design взаимодействуют / взаимодействуют, отправляя 9X_object-oriented-design сообщения, а не считывая / устанавливая 9X_protected состояние.

Взамен они предлагают очень мало 9X_oop преимуществ. Я не обязательно удаляю их 9X_oop из чужого кода, но сам я ими не пользуюсь.

7
0

Ответ #7

Ответ на вопрос: Должны ли вы когда-либо использовать защищенные переменные-члены?

Для записи, в пункте 24 документа "Exceptional 9X_oo C++" в одной из сносок Саттер пишет «вы 9X_ood бы никогда не написали класс, у которого 9X_oops есть общедоступная или защищенная переменная-член. Не 9X_oop так ли? (Несмотря на плохой пример, установленный 9X_oop некоторыми библиотеками.)»

5
0

Ответ #8

Ответ на вопрос: Должны ли вы когда-либо использовать защищенные переменные-члены?

В большинстве случаев использовать protected 9X_oop опасно, потому что вы несколько нарушаете 9X_oo инкапсуляцию вашего класса, которая вполне 9X_object-orientation может быть разбита плохо спроектированным 9X_ood производным классом.

Но у меня есть один 9X_oop хороший пример: допустим, у вас есть какой-то 9X_object-oriented универсальный контейнер. У него есть внутренняя 9X_oops реализация и внутренние средства доступа. Но 9X_object-oriented вам нужно предложить как минимум 3 публичных 9X_oo доступа к своим данным: map, hash_map, vector-like. Тогда 9X_object-oriented-modeling у вас будет что-то вроде:

template class Base { // etc. protected TContainer container ; } template class DerivedMap : public Base > { /* etc. */ } template class DerivedHashMap : public Base > { /* etc. */ } template class DerivedVector : public Base > { /* etc. */ } 

Я использовал такой 9X_object-oriented-design код менее месяца назад (так что код взят 9X_object-oriented-design из памяти). Поразмыслив, я считаю, что хотя 9X_object-oriented общий контейнер Base должен быть абстрактным 9X_oops классом, даже если он может жить вполне 9X_object-oriented-modeling нормально, потому что использование напрямую 9X_object-oriented Base было бы такой болью, что его следует 9X_object-orientation запретить.

Сводка Таким образом, вы защитили данные, используемые 9X_oo-design производным классом. Тем не менее, мы должны 9X_oops принять во внимание тот факт, что базовый 9X_oops класс должен быть абстрактным.

4
0

Ответ #9

Ответ на вопрос: Должны ли вы когда-либо использовать защищенные переменные-члены?

Короче говоря, да.

Защищенные переменные-члены 9X_oop позволяют получить доступ к переменной из 9X_object-oriented-modeling любых подклассов, а также из любых классов 9X_object-oriented-design в том же пакете. Это может быть очень полезно, особенно 9X_oops для данных только для чтения. Однако я не 9X_oo считаю, что они когда-либо необходимы, потому 9X_oop что любое использование защищенной переменной-члена 9X_protected может быть воспроизведено с использованием 9X_object-oriented-modeling частной переменной-члена и пары геттеров 9X_object-oriented и сеттеров.

3
1

  • И наоборот, частные переменные-члены также ...

Ответ #10

Ответ на вопрос: Должны ли вы когда-либо использовать защищенные переменные-члены?

Подробная информация о модификаторах доступа 9X_oo .Net go here

У защищенных переменных-членов нет 9X_object-oriented реальных преимуществ или недостатков, это 9X_ood вопрос того, что вам нужно в вашей конкретной 9X_object-oriented-modeling ситуации. Обычно принято объявлять переменные-члены 9X_object-oriented-design как частные и разрешать внешний доступ через 9X_oo свойства. Кроме того, некоторые инструменты 9X_object-oriented (например, некоторые преобразователи O/R) ожидают, что 9X_object-orientation данные объекта будут представлены свойствами, и 9X_object-orientation не распознают общедоступные или защищенные 9X_ood переменные-члены. Но если вы знаете, что 9X_oops хотите, чтобы ваши подклассы (и ТОЛЬКО ваши 9X_oo-design подклассы) имели доступ к определенной переменной, нет 9X_oo-design причин не объявлять ее защищенной.

2
0