В чем разница между
public
,private
иprotected
наследование в C ++?
Все вопросы, которые я нашел на SO, касаются конкретных случаев.
c++
inheritance
encapsulation
access-specifier
c++-faq
Арсен Хачатурян
источник
источник
SomeBase
похоже на жестко запрограммированный способ создания анонимного члена типаSomeBase
. Это, как и любой другой член, имеет спецификатор доступа, который оказывает такой же контроль на внешний доступ.ВАЖНОЕ ПРИМЕЧАНИЕ: все классы B, C и D содержат переменные x, y и z. Это просто вопрос доступа.
Об использовании защищенного и частного наследования вы можете прочитать здесь .
источник
Ограничение видимости наследования сделает код неспособным увидеть, что какой-то класс наследует другой класс: неявные преобразования из производного в базовое не будут работать, и
static_cast
из базового в производное также не будет работать.Только члены / друзья класса могут видеть личное наследование, и только члены / друзья и производные классы могут видеть защищенное наследование.
общественности наследство
ИС-А наследство. Кнопка - это окно, и везде, где требуется окно, кнопка также может быть передана.
защищенный наследство
Защищено реализовано в сроках. Редко полезно. Используется
boost::compressed_pair
для извлечения из пустых классов и сохранения памяти с помощью оптимизации пустого базового класса (в приведенном ниже примере шаблон не используется, чтобы оставаться в точке):частное наследство
Реализована-в-члены Организации. Использование базового класса только для реализации производного класса. Полезно с чертами и если размер имеет значение (пустые черты, которые содержат только функции, будут использовать пустую оптимизацию базового класса). Часто сдерживание - лучшее решение, все же. Размер строк имеет решающее значение, поэтому здесь его часто используют.
общественности член
заполнитель
Accessors
защищенный член
Предоставление расширенного доступа для производных классов
частный член
Сохранить детали реализации
Обратите внимание, что приведения в стиле C преднамеренно позволяют приводить производный класс к защищенному или частному базовому классу определенным и безопасным способом, а также приводить в другом направлении. Этого следует избегать любой ценой, потому что это может сделать код зависимым от деталей реализации - но при необходимости вы можете использовать эту технику.
источник
Эти три ключевых слова также используются в совершенно другом контексте для определения модели наследования видимости .
В этой таблице собраны все возможные комбинации объявления компонента и модели наследования, представляющие итоговый доступ к компонентам, когда подкласс полностью определен.
Таблица выше интерпретируется следующим образом (взгляните на первый ряд):
Пример:
В результате доступ к переменным
p
,q
,r
в классе Subsub не никто .В результате доступ к переменным
y
,z
в классе Sub будет защищен и для переменнойx
не является ни .Теперь давайте определим подкласс:
Определенный класс с именем Sub, который является подклассом класса с именем
Super
или этотSub
класс является производным отSuper
класса. ВSub
класс вводит ни новых переменных , ни новых функций. Означает ли это, что любой объектSub
класса наследует все черты после того, какSuper
класс фактически является копиейSuper
класса?нет . Это не так.
Если мы скомпилируем следующий код, мы получим только ошибки компиляции, говорящие об этом
put
иget
методы недоступны. Почему?Когда мы опускаем спецификатор видимости, компилятор предполагает, что мы собираемся применить так называемое частное наследование . Это означает, что все общедоступные компоненты суперкласса превращаются в частные доступ, приватные компоненты суперкласса вообще не будут доступны. Следовательно, это означает, что вы не можете использовать последний внутри подкласса.
Мы должны сообщить компилятору, что мы хотим сохранить ранее использованную политику доступа.
Объекты
Sub
класса могут делать «почти» те же вещи, что и их старшие братья и сестры, созданные изSuper
класса. «Почти», потому что тот факт, что он является подклассом, также означает, что класс потерял доступ к закрытым компонентам суперкласса . Мы не можем написать функцию-членSub
класса, которая могла бы напрямую манипулировать переменной хранения.Это очень серьезное ограничение. Есть ли обходной путь?
Да .
Третий уровень доступа называется защищенным . Ключевое слово protected означает, что помеченный им компонент ведет себя как общедоступный при использовании любым из подклассов и выглядит как частный для остального мира . - Это верно только для публично унаследованных классов (например, суперкласса в нашем примере) -
Как вы видите в примере кода, мы добавили в
Sub
класс новую функциональность, и она делает одну важную вещь: она обращается к переменной хранения из класса Super .Это было бы невозможно, если бы переменная была объявлена как приватная. В области видимости основной функции переменная все равно остается скрытой, поэтому, если вы напишите что-то вроде:
Компилятор сообщит вам, что это
error: 'int Super::storage' is protected
.Наконец, последняя программа выдаст следующий вывод:
источник
Это связано с тем, как открытые члены базового класса выставляются из производного класса.
Как указывает Литб, публичное наследование - это традиционное наследование, которое вы увидите в большинстве языков программирования. То есть он моделирует отношения "IS-A". Частное наследование, то, что AFAIK свойственно C ++, является отношением «РЕАЛИЗОВАНО В УСЛОВИЯХ». То есть вы хотите использовать открытый интерфейс в производном классе, но не хотите, чтобы пользователь производного класса имел доступ к этому интерфейсу. Многие утверждают, что в этом случае вы должны агрегировать базовый класс, то есть вместо того, чтобы базовый класс был закрытым, сделать член в производном для повторного использования функциональности базового класса.
источник
Тип наследования : Объект, унаследованный как :
источник
1) Общественное наследство :
а. Частные члены Базового класса не доступны в производном классе.
б. Защищенные члены базового класса остаются защищенными в производном классе.
с. Открытые члены Базового класса остаются публичными в производном классе.
Итак, другие классы могут использовать открытые члены класса Base через объект класса Derived.
2) Защищенное наследование :
а. Частные члены Базового класса не доступны в производном классе.
б. Защищенные члены базового класса остаются защищенными в производном классе.
с. Открытые члены Базового класса тоже становятся защищенными членами Производного класса.
Таким образом, другие классы не могут использовать открытые члены класса Base через объект класса Derived; но они доступны для подкласса Derived.
3) Частное наследство :
а. Частные члены Базового класса не доступны в производном классе.
б. Защищенные и публичные члены базового класса становятся частными членами производного класса.
Таким образом, никакие члены базового класса не могут быть доступны другим классам через объект класса Derived, поскольку они являются частными в классе Derived. Таким образом, даже подкласс класса Derived не может получить к ним доступ.
источник
Публичное наследование моделирует отношения IS-A. С
каждый
D
естьB
.Частное наследование моделирует отношения IS-IMPLEMENTED-USING (или как там это называется). С
a не
D
является a , но каждый использует его в своей реализации. Частное наследование всегда можно устранить, используя вместо этого сдерживание:B
D
B
Это
D
также может быть реализовано с использованиемB
, в данном случае, с помощью егоb_
. Сдерживание - это менее тесная связь между типами, чем наследование, поэтому в целом оно должно быть предпочтительным. Иногда использование сдерживания вместо частного наследования не так удобно, как частное наследование. Часто это слабое оправдание лени.Я не думаю, что кто-нибудь знает, что
protected
модели наследования. По крайней мере, я еще не видел убедительного объяснения.источник
D
происходит от частногоD
, он может переопределить виртуальные функцииB
. (Если, например,B
это интерфейс наблюдателя, то онD
может реализовать его и перейтиthis
к функциям, требующим наличия интерфейса, при этом каждый не сможет использовать егоD
в качестве наблюдателя.) Кроме того,D
можно выборочно сделать членовB
доступными в его интерфейсе, выполняяusing B::member
. Оба синтаксически неудобно для реализации, когдаB
является членом.protected
Я нашел полезное наследование сvirtual
базовым классом иprotected
ctor:struct CommonStuff { CommonStuff(Stuff*) {/* assert !=0 */ } }; struct HandlerMixin1 : protected virtual CommonStuff { protected: HandlerMixin1() : CommonStuff(nullptr) {} /*...*/ }; struct Handler : HandlerMixin1, ... { Handler(Stuff& stuff) : CommonStuff(&stuff) {} };
Если вы публично наследуете от другого класса, все знают, что вы наследуете, и вы можете полиморфно использоваться кем угодно через указатель базового класса.
Если вы наследуете защищенно, только ваши дети смогут использовать вас полиморфно.
Если вы наследуете конфиденциально, только вы сами сможете выполнять методы родительского класса.
Что в основном символизирует знания остальных классов о ваших отношениях с родительским классом
источник
К защищенным членам данных могут обращаться любые классы, которые наследуются от вашего класса. Частные данные участников, однако, не могут. Допустим, у нас есть следующее:
Внутри вашего расширения до этого класса ссылки
this.myPrivateMember
не будут работать. Тем не менее,this.myProtectedMember
будет. Значение по-прежнему инкапсулировано, поэтому, если у нас будет вызван экземпляр этого классаmyObj
, онmyObj.myProtectedMember
не будет работать, поэтому он похож по функции на частный член данных.источник
Основываясь на этом примере для Java ... Я думаю, что столик стоит тысячу слов :)
источник
Резюме:
При наследовании вы можете (на некоторых языках) изменить тип защиты элемента данных в определенном направлении, например, с защищенного на общедоступный.
источник
Частный:
Закрытые члены базового класса могут быть доступны только членам этого базового класса.
Общественность:
К открытым членам базового класса могут обращаться члены этого базового класса, члены его производного класса, а также члены, которые находятся за пределами базового класса и производного класса.
Защищено:
Защищенные члены базового класса могут быть доступны как членам базового класса, так и членам его производного класса.
Короче говоря:
частный : база
защищенный : базовый + производный
public : base + производная + любой другой участник
источник
Я нашел простой ответ и подумал о том, чтобы опубликовать его и для дальнейшего использования.
Это из ссылок http://www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/
источник
По сути это защита доступа открытых и защищенных членов базового класса в производном классе. При публичном наследовании производный класс может видеть открытых и защищенных членов базы. С частным наследством это не может. С защищенным, производным классом и любыми производными классами, которые могут их видеть.
источник