Protected c что это
Все поля, методы и остальные компоненты класса имеют модификаторы доступа . Модификаторы доступа позволяют задать допустимую область видимости для компонентов класса. То есть модификаторы доступа определяют контекст, в котором можно употреблять данную переменную или метод.
В языке C# применяются следующие модификаторы доступа:

- private : закрытый или приватный компонент класса или структуры. Приватный компонент доступен только в рамках своего класса или структуры.
- private protected : компонент класса доступен из любого места в своем классе или в производных классах, которые определены в той же сборке.
- file : добавлен в версии C# 11 и применяется к типам, например, классам и структурам. Класс или структура с такми модификатором доступны только из текущего файла кода.
- protected : такой компонент класса доступен из любого места в своем классе или в производных классах. При этом производные классы могут располагаться в других сборках.
- internal : компоненты класса или структуры доступен из любого места кода в той же сборке, однако он недоступен для других программ и сборок.
- protected internal : совмещает функционал двух модификаторов protected и internal . Такой компонент класса доступен из любого места в текущей сборке и из производных классов, которые могут располагаться в других сборках.
- public : публичный, общедоступный компонент класса или структуры. Такой компонент доступен из любого места в коде, а также из других программ и сборок.
Стоит отметить, что эти модификаторы могут применяться как к компонентам класса, так и к компонентам структуры за тем исключением, что структуры не могут использовать модификаторы private protected , protected и protected internal , поскольку структуры не могут быть унаследованы.
Все классы и структуры, определенные напрямую вне других типов (классов и структур) могут иметь только модификаторы public , file или internal .
Мы можем явно задать модификатор доступа, а можем его и не указывать:
public class Person < string name; public Person(string name) < this.name = name; >public void Print() => Console.WriteLine($"Name: "); >
Если для компонентов не определен модификатор доступа, то по умолчанию для них применяется модификатор private . Например, в примере выше переменная name неявно будет иметь модификатор private .
Классы и структуры, которые объявлены без модификатора и которые расположены вне других типов, по умолчанию имеют доступ internal , а вложенные классы и структуры, как и остальные компоненты классов/структур имеют модификатор private . Например:
class Phone < struct Camera < >>
Здесь класс Phone не является вложенным ни в один другой класс/структуру, поэтому неявно имеет модификатор internal . А структура Camera является вложенной, поэтому, как и другие компоненты класса, неявно имеет модификатор private
Модификаторы в рамках текущего проекта
Посмотрим на примере и создадим следующий класс State:
class State < // все равно, что private string defaultVar; string defaultVar ="default"; // поле доступно только из текущего класса private string privateVar = "private"; // доступно из текущего класса и производных классов, которые определены в этом же проекте protected private string protectedPrivateVar = "protected private"; // доступно из текущего класса и производных классов protected string protectedVar = "protected"; // доступно в любом месте текущего проекта internal string internalVar = "internal"; // доступно в любом месте текущего проекта и из классов-наследников в других проектах protected internal string protectedInternalVar = "protected internal"; // доступно в любом месте программы, а также для других программ и сборок public string publicVar = "public"; // по умолчанию имеет модификатор private void Print() =>Console.WriteLine(defaultVar); // метод доступен только из текущего класса private void PrintPrivate() => Console.WriteLine(privateVar); // доступен из текущего класса и производных классов, которые определены в этом же проекте protected private void PrintProtectedPrivate() => Console.WriteLine(protectedPrivateVar); // доступен из текущего класса и производных классов protected void PrintProtected() => Console.WriteLine(protectedVar); // доступен в любом месте текущего проекта internal void PrintInternal() => Console.WriteLine(internalVar); // доступен в любом месте текущего проекта и из классов-наследников в других проектах protected internal void PrintProtectedInternal() => Console.WriteLine(protectedInternalVar); // доступен в любом месте программы, а также для других программ и сборок public void PrintPublic() => Console.WriteLine(publicVar); >
Так как класс State не имеет явного модификатора, по умолчанию он имеет модификатор internal , поэтому он будет доступен из любого места данного проекта, однако не будет доступен из других программ и сборок.
Класс State имеет шесть полей для каждого уровня доступа. Плюс одна переменная без модификатора, которая является закрытой (private) по умолчанию. А также определено семь методов с разными модификаторами, которые выводят значения соответствующих переменных на консоль. Поскольку все модификаторы позволяют использовать компоненты класса внутри данного класса, то и все переменные класса, в том числе закрытые, у нас доступны всем его методам, так как все находятся в контексте класса State.
Теперь посмотрим, как мы сможем использовать переменные класса State в другом классе, который, допустим, будет называться StateConsumer и который расположен в том же проекте :
class StateConsumer < public void PrintState() < State state = new State(); // обратиться к переменной defaultVar у нас не получится, // так как она имеет модификатор private и класс StateConsumer ее не видит Console.WriteLine(state.defaultVar); //Ошибка, получить доступ нельзя // то же самое относится и к переменной privateVar Console.WriteLine(state.privateVar); // Ошибка, получить доступ нельзя // обратиться к переменной protectedPrivateVar не получится, // так как класс StateConsumer не является классом-наследником класса State Console.WriteLine(state.protectedPrivateVar); // Ошибка, получить доступ нельзя // обратиться к переменной protectedVar тоже не получится, // так как класс StateConsumer не является классом-наследником класса State Console.WriteLine(state.protectedVar); // Ошибка, получить доступ нельзя // переменная internalVar с модификатором internal доступна из любого места текущего проекта // поэтому можно получить или изменить ее значение Console.WriteLine(state.internalVar); // переменная protectedInternalVar так же доступна из любого места текущего проекта Console.WriteLine(state.protectedInternalVar); // переменная publicVar общедоступна Console.WriteLine(state.publicVar); >>
Таким образом, в классе StateConsumer мы смогли только обратиться к переменным internalVar, protectedInternalVar и publicVar, так как их модификаторы позволяют использовать в данном контексте.
Аналогично дело обстоит и с методами:
class StateConsumer < public void PrintState() < State state = new State(); state.Print(); //Ошибка, получить доступ нельзя state.PrintPrivate(); // Ошибка, получить доступ нельзя state.PrintProtectedPrivate(); // Ошибка, получить доступ нельзя state.PrintProtected(); // Ошибка, получить доступ нельзя state.PrintInternal(); // норм state.PrintProtectedInternal(); // норм state.PrintPublic(); // норм >>
Здесь нам оказались доступны только три метода: PrintInternal, PrintProtectedInternal, PrintPublic, которые имееют соответственно модификаторы internal, protected internal, public.
Модификаторы в рамках сборок
Допустим, у нас есть проект (и соответственно сборка) MyLib, в которой определены три класса:
namespace MyLib; // класс доступен из других сборок public class PublicState < internal void PrintInternal() =>Console.WriteLine(«internal»); protected internal void PrintProtectedInternal() => Console.WriteLine(«protected internal»); public void PrintPublic() => Console.WriteLine(«public»); > // класс доступен только в текущей сборке — по умолчанию internal class DefaultState < >// класс доступен только в текущей сборке internal class InternalState
Здесь классы DefaultState и InternalState имеют модификатор internal , поэтому доступны только в текущем проекте.
Класс PublicState модификатором public доступен из других проектов. Однако его метод PrintInternal() доступен только в текущем проекте. Вне текущего проекта доступен только его метод PrintPublic и PrintProtectedInternal() (доступен в другом проекте только в классах-наследниках).
Допустим, мы подключаем сборку этого проекта MyLib в другой проект, где есть класс StateConsumer:
using MyLib; class StateConsumer < public void PrintState() < // Ошибка DefaultState - по умолчанию internal, поэтому нет доступа DefaultState defaultState = new DefaultState(); // Ошибка InternalState - internal, поэтому нет доступа InternalState internalState = new InternalState(); // норм, PublicState - public, доступен из других программ PublicState publicState = new PublicState(); // Ошибка, нет доступа - метод доступен только в свой сборке publicState.PrintInternal(); // Ошибка, нет доступа - StateConsumer НЕ является классом-наследником от класса PublicState, // поэтому метод не доступен publicState.PrintProtectedInternal(); // нет доступа // норм - общедоступный метод publicState.PrintPublic(); // норм >>

В классе StateConsumer есть доступ только к классу PublicState и его методу PrintPublic , потому что они имеют модификатор public . К остальной функциональности подключенной сборки StateConsumer доступа не имеет.
Благодаря такой системе модификаторов доступа можно скрывать некоторые моменты реализации класса от других частей программы.
Файл как область видимости
C# 11 был добавлен еще один модификатор видимости — file , который применяется к классам, структурам, делегатам, перечислениям, интерфейсам. Типы с этим модификатором могут использоваться только внутри текущего файла кода.
file class Person
Данный модификатор не может использоваться в паре с другими модификаторами.
C++ для всех
Тема довольно избита, однако, я всё-таки решил начать с неё. Думаю, новичкам будет полезно.
Итак, public, private и protected — это модификаторы доступа, а не видимости, как ошибочно думают некоторые. Private члены видны снаружи класса, но не доступны.
Теперь кратко, кому какой доступ они предоставляют.
- Public — доступ открыт всем, кто видит определение данного класса.
- Private — доступ открыт самому классу (т.е. функциям-членам данного класса) и друзьям (friend) данного класса, как функциям, так и классам.
- Protected — доступ открыт классам, производным от данного.
Далее приведены примеры доступа с указанием какие поля в каких местах программы доступны.
class some < friend void f(some&); public: int a_; protected: int b_; private: int c_; >; void f(some& obj) < obj.a_ = 0; // OK obj.b_ = 0; // OK obj.c_ = 0; // OK >void g(some& obj) < obj.a_ = 0; // OK obj.b_ = 0; // compile time error obj.c_ = 0; // compile time error >class derived : public some < derived() < a_ = 0; // OK b_ = 0; // OK c_ = 0; // compile time error >>;
В C++ существует public-наследование, private-наследование и protected-наследование. В зависимости от того, какой тип используется, изменяется доступ к членам базового класса для клиентов производного. В таблице сведена информация об этом изменении.
| Исходный модификатор доступа | |||
| public | private | protected | |
| public-наследование | public | private | protected |
| private-наследование | private | private | private |
| protected-наследование | protected | private | protected |
Следует добавить, что производный класс может изменить модификатор доступа с protected на public, разместив using объявление в соответствующей секции класса:
class some < public: int a; protected: int b; private: int c; >; class derived : public some < public: using some::b; >; void f(derived& obj) < obj.b = 0; // OK >
Напоследок приведу несколько приёмов, с помощью которых можно «достучаться» до закрытых функций или данных. Допустим, у нас есть класс some и нам нужно обнулить закрытую переменную c:
-
Модифицировать определение класса, добавив друга (функцию или класс)
class some < friend class some_friend; public: int a; protected: int b; private: int c; >; class some_friend < public: static void hack(some& obj) < obj.c = 0; >>;
#define private public class some < public: int a; protected: int b; private: int c; >; void hack(some& obj)
class some < public: int a; protected: int b; private: int c; >; class hack_some < public: int a; int b; int c; >; void h(some& obj) < reinterpret_cast(&obj)->c = 0; >
class some < public: int a; template void func(void) < a = b + c; >protected: int b; private: int c; >; class hack_template_param<>; template void some::func(void) < c = 0; >void hack(void) < some o; o.func(); >;
Очевидно, что способ с reinterpret_cast работает только для доступа к закрытым членам данных или вызова виртуальных функций. Остальные же способы позволяют как модифицировать закрытые данные, так и вызывать закрытые невиртуальные методы.
UPD (31.08.2013): Для компиляторов GCC и CLANG существует опция -fno-access-control, которая позволяет отключить контроль доступа к членам класса со стороны компилятора.
UPD (31.08.2013): Переформатировал исходный код под использование встроенного плагина вордпресса.
Protected c что это
Написание статьи о protected привело к написанию этой. Я понял для какого из случаев предназначены модификаторы доступа private , public и protected .
- private — Модификатор доступа, обозначющий, что программист будет использовать элементы класса только внутри непосредственно основного своего класса.
- public — Модификатор доступа, обозначающий, что программист будет использовать элементы класса либо в других частях программы, либо в других классах.
- protected — Модификатор доступа, обозначающий, что программист будет использовать элементы класса либо внутри непосредственно своего основного класса, либо непосредственно в своём потомке-классе.
Сейчас я попробую описать то же самое используя художественный стиль (может кому-то пригодиться).
Класс-наследник имеет поля и функции-члены базового класса, но не имеет права обращаться к собственным ( private ) полям и функциям базового класса. Вот и выходит так, что у основного класса есть такая часть, которую от сердца ему не оторвать: все наследники о ней знают, но использовать её не могут, так как родитель отказался передавать ту часть по наследству. Такая часть — это private .
Да вот мучает совесть родителя, не может родитель оставить детей без наследства, решает передать некоторую часть того, что у него есть, всем своим потомкам. Передаётся эта тайна от родителя к потомку, но скрыта она от всех посторонних и доступна исключительно детям собственным класса. Такая часть — это protected .
А чтобы не вспоминали родителя словом плохим, родитель передаёт еще часть наследства своим потомкам, и эта часть наследства озвучивается публично. Коли о наследстве озвучивается публично, то та часть, о которой озвучивается, может попасть не в руки потомков и использовать её сможет любой шарлатан. Такая часть — public .
Так вот обстоят дела с наследованием.
Иногда задают вопрос: » Если мы наследуем класс, наследуются ли приватные поля (члены)? . Ответ — да. Это легко проверить.
//Приватные поля наследуются clang Листинг #1
using namespace std ;
int a , b , c ; //По умолчанию private.
class B : public A //Применили наследование и на основе класса A создали класс B
class C //Независимый класс
cout < < sizeof ( A ) < < endl ; //Вывели на экран размер объекта от класса A
cout < < sizeof ( B ) < < endl ; //Вывели на экран размер объекта от класса B
cout < < sizeof ( C ) < < endl ; //Вывели на экран размер объекта от класса C
Посмотрим в код. С одной стороны у нас один класс с приватными переменными и два класса: один однозначно пустой, а второй неопределённого состояния: ни то пустой, ни то с наследством. Несложно догадаться, что пустой у нас класс C , а вот класс B в неопределённом для многих из нас, новичков, состоянии. Чтобы проверить, были ли унаследованы поля, можно сравнить размеры классов. Если класс B не унаследовал ничего, то размер его будет равен размеру пустого класса, а если унаследовал, то размер его будет равен размеру класса A .
В зависимости от системы результаты на экран могут быть вывдены разные, но в любом случае получится, что A == B, а размер C скорее всего будет сильно меньше (в моём случае А==12, B==12, C==1). Это обозначает однозначно, что поля потомок к себе получил. Несмотря на то, что использовать мы их не можем, они в потомке оказались. Вот мы и проверили, что приватные поля наследуются, висят в памяти. А ещё можем сделать вывод, что кроме пожирания памяти и не делают ничего, и использовать их нельзя. Одним словом — Паразиты.
- Приватные элементы наследуются. Хотя всё равно могут быть несогласные. Важно понимать, что под наследованием могут иметь в виду сам механизм наследования, а не получаемый от наследования эффект.
- Конструкторы и деструкторы не наследуются.
- Все перегруженные операции наследуются.
- начиная С++11 конструкторы (с рядом исключений) можно наследовать явно, путем применения using-декларации.
C++. Модификаторы доступа private, protected, public. Инкапсуляция данных в классе
C++. Модификаторы доступа private , protected , public . Инкапсуляция данных в классе
Поиск на других ресурсах:
1. Случаи применения модификаторов доступа private , protected , public
Парадигма объектно-ориентированного программирования предусматривает возможность задания уровня доступности элементов классов. Уровень доступности позволяет регулировать доступ к данным и методам класса. Одни элементы класса могут быть общедоступны, другие — скрыты. Сокрытие данных и методов в классе называется инкапсуляцией.
В языке C++ уровень доступности определяется с помощью специальных модификаторов private , protected , public . Применение этих модификаторов может быть использовано в двух случаях:
- в случае объявления элементов класса. Этот случай рассматривается в данной теме;
- в случае наследования классов. Более подробно о применении модификаторов доступа при наследовании классов можно посмотреть здесь .
2. Применение модификаторов доступа для элемента класса
2.1. Модификатор доступа private . Особенности использования
Если в классе объявляется элемент (функция, член данных) в разделе private , то для него действуют следующие правила доступа:
- элемент недоступен любым экземплярам методов других классов или методов, которые не есть «дружественными» к класу (рисунок 1);
- элемент недоступен из унаследованных классов (рисунок 2);
- элемент доступен из методов, которые реализованы в классе (рисунок 3);
- элемент доступен из дружественных функций (рисунок 4);
- элемент доступен из методов дружественных классов (рисунок 5).

Рисунок 1. Модификатор доступа private . Нет доступа из экземпляра класса к private -элементу value класса

Рисунок 2. Модификатор доступа private . Нет доступа к private -элементу класса из унаследованного класса

Рисунок 3. Модификатор доступа private . Доступ к элементу класса из внутреннего метода класса

Рисунок 4. Модификатор доступа private . Доступ к элементу класса из дружественной функции (метода)
Если в коде, изображенном на рисунке 4, в объявлении класса A перед именем функции SetValue() убрать ключевое слово friend , то доступа к переменной value класса не будет. Как результат, в функции SetValue() в строке
objA.value = 33;
компилятор будет выдавать ошибку наподобие
Member A::value is inaccessible

Рисунок 5. Модификатор доступа private . Доступ к private -элементу класса из метода дружественного класса
2.2. Модификатор доступа public . Особенности использования
Если в классе определен элемент с модификатором доступа public , в этом случае справедливо правило:
- элемент доступен всем методам в программе.
Исключение составляет случай, когда клас унаследован как private . Тогда даже public-элементы этого класса будут недоступны в унаследованных классах. Более подробно об использовании модификаторов доступа для класса можно прочитать здесь .

Рисунок 6. Модификатор доступа public . Доступ к элементу класса из любого метода в программе

Рисунок 7. Модификатор доступа public . Доступ из унаследованного класса
2.3. Модификатор доступа protected . Особенности применения
Модификатор доступа protected актуален в случаях, когда классы образуют иерархию наследования. Если в классе объявлен элемент (функция, член данных) с модификатором доступа protected , то для него действуют следующие правила:
- элемент класса недоступен из любого внешнего метода (рисунок 8) если этот метод не является дружественным;
- элемент класса доступен из внутренних методов класса (рисунок 8). Здесь следует заметить, что protected -элемент класса также доступен из экземпляра класса, если этот экземпляр объявляется во внутреннем методе класса;
- элемент класса доступен из дружественных функций класса (рисунок 9);
- элемент класса доступен из методов дружественного класса (рисунок 9);
- элемент класса доступен из методов унаследованного класса (рисунок 10);
- элемент класса недоступен из экземпляров унаследованного класса (рисунок 11). Это правило не касается «дружественных» методов и методов «дружественных» классов.

Рисунок 8. Модификатор доступа protected . Нет доступа из экземпляра класса, если этот экземпляр создан в «недружественном» методе
На рисунке 8 продемонстрованы два вида доступа к protected -элементу класса:
- через экземпляр (объект) класса, который объявляется во внутреннем методе класса Method() ;
- непосредственный доступ как к члену данных класса.

Рисунок 9. Модификатор доступа protected . Доступ из «дружественных» методов и методов «дружественных» классов

Рисунок 10. Модификатор доступа protected . Доступ из методов унаследованного класса

Рисунок 11. Модификатор доступа protected . Нет доступа из экземпляров унаследованного класса