Должны ли вы когда-либо использовать защищенные переменные-члены?
Стоит ли вам когда-либо использовать защищенные 9X_protected переменные-члены? Каковы преимущества и 9X_object-oriented какие проблемы это может вызвать?
Ответ #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 возможность изменить его позже.
- @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 вещах.
Ответ #3
Ответ на вопрос: Должны ли вы когда-либо использовать защищенные переменные-члены?
В настоящее время считается, что они вызывают 9X_object-orientation чрезмерную связь между производными классами 9X_oop и их базами.
У них нет особого преимущества 9X_oo перед защищенными методами/свойствами (когда-то 9X_oo-design они могли иметь небольшое преимущество в 9X_object-oriented производительности), и они также больше 9X_oop использовались в эпоху, когда было в моде 9X_oo-design очень глубокое наследование, чего сейчас 9X_oop нет. .
- Разве «отсутствие особого преимущества перед защищенными методами / свойствами» не должно быть «особым преимуществом перед * частными ...
Ответ #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 поведение через сеттеры или геттеры.
Ответ #5
Ответ на вопрос: Должны ли вы когда-либо использовать защищенные переменные-члены?
В общем, я бы сохранил ваши защищенные переменные-члены 9X_oop в редких случаях, когда вы полностью контролируете 9X_oo код, который их также использует. Если вы 9X_object-oriented-design создаете публичный API, я бы сказал никогда. Ниже 9X_oo мы будем называть переменную-член «свойством» объекта.
Вот 9X_object-oriented что ваш суперкласс не может делать после того, как 9X_oop переменная-член будет защищена, а не закрыта 9X_object-orientation с аксессорами:
-
лениво создайте значение на 9X_ood лету, когда свойство читается. Если вы добавите 9X_oo защищенный метод получения, вы можете лениво 9X_object-oriented-design создать значение и передать его обратно.
-
знать, когда 9X_protected свойство было изменено или удалено. Это 9X_object-oriented-design может привести к ошибкам, когда суперкласс 9X_oop делает предположения о состоянии этой переменной. Создание 9X_object-oriented защищенного метода установки для переменной 9X_object-oriented-modeling сохраняет этот контроль.
-
Установите точку 9X_object-oriented останова или добавьте вывод отладки при 9X_ood чтении или записи переменной.
-
Переименуйте 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 труднее, чем сейчас.
Ответ #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
Ответ на вопрос: Должны ли вы когда-либо использовать защищенные переменные-члены?
Для записи, в пункте 24 документа "Exceptional 9X_oo C++" в одной из сносок Саттер пишет «вы 9X_ood бы никогда не написали класс, у которого 9X_oops есть общедоступная или защищенная переменная-член. Не 9X_oop так ли? (Несмотря на плохой пример, установленный 9X_oop некоторыми библиотеками.)»
Ответ #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 класс должен быть абстрактным.
Ответ #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 и сеттеров.
- И наоборот, частные переменные-члены также ...
Ответ #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 причин не объявлять ее защищенной.
-
14
-
17
-
5
-
7
-
4
-
27
-
15
-
6
-
10
-
8
-
9
-
4
-
2
-
2
-
1
-
5
-
5
-
7
-
2
-
5
-
5
-
4
-
4
-
5
-
2
-
5
-
7
-
4
-
3
-
3
-
3
-
1
-
5
-
7
-
7
-
2
-
4
-
5
-
6
-
6
-
5
-
2
-
2
-
5
-
2
-
18
-
16
-
38
-
8
-
11