Члены класса, объявленные как protected, сохраняют все ограничения членов класса, объявленных как private, но дочерние классы могут к ним обращаться.
Таким образом, раздел protected предназначен для создания расширенной зоны видимости для наследников данного класса и одновременно реализует защиту от внешнего доступа со стороны объектов, не являющихся наследниками данного класса.
Модификатор public
Рти члены класса РІРёРґРёРјС‹ всем Рё отовсюду, Рё являются интерфейсом класса, то есть набором полей Рё методов, специально определенных для взаимодействия СЃ внешним РјРёСЂРѕРј.
Модификатор friend
От обсуждения предыдущих трех директив возникает устойчивое впечатление, что классы в своем поведении очень похожи на людей. У них есть приватная зона, куда не допускается никто, зона ограниченного доступа, куда допускаются только «члены семьи», и публичная зона, которую показывают всем. Еще большее сходство с людьми классы обретают тогда, когда мы узнаем, что они могут дружить. То есть реализация языка C++ позволяет совершенно посторонним классам по-дружески (friend) получать доступ к подробностям реализации класса. Можно объявить с этим модификатором как отдельные члены класса, так и весь класс целиком. Директива friend предназначена для обеспечения доступа к отдельным классам, к private и protected областям текущего класса, к отдельным членам из этих областей, или ко всем членам класса сразу.
Упражнение 5.1 (продолжение)
22. В ранее созданном классе Dog нужно перенести поле age из области public в область private, как показано в листинге 5.11.
Листинг 5.11
class Dog {
private:
int age;
public:
Dog();
…
23. Теперь нужно попробовать откомпилировать проект. Но будет выведено сообщение об ошибке 'age': cannot access private member declared in class 'Dog'. Член класса с модификатором private не виден извне, и попытка получить к нему доступ в коде обработчика кнопки Assign обречена на неудачу.
24. Переместить поле age в область protected, как показано в листинге 5.12.
Листинг 5.12
class Dog {
protected:
int age;
public:
Dog();
…
25. Попытка откомпилировать проект закончится так же, как и предыдущая, поскольку снова происходит обращение к полю protected извне класса. Когда поле находилось в зоне public, такой ошибки не было.
26.В Рзменить метод Add класса CleverDog, как показано РІ листинге 5.13.
Листинг 5.13
class CleverDog: public Dog {
void Add(int x, int y){
age= 200;
};
27.В Рзменить обработчик щелчка РЅР° РєРЅРѕРїРєРµ Assign, как показано РІ листинге 5.14. Листинг 5.14
case IDC_BUTTON3:
Dogs[0]->Add(0,0);
break;
28. После внесения этих изменений проект нормально компилируется, и нажатие кнопки Assign не приводит к возникновению ошибки. Поскольку класс Dog является базовым классом для CleverDog, то метод Add дочернего класса получает доступ к полю age, объявленному в секции protected базового класса.
Перегрузка методов
Гибкость использования классов расширяется Р·Р° счет использования перегрузки методов. Перегрузка методов позволяет объявлять РІ РѕРґРЅРѕРј классе несколько методов СЃ РѕРґРЅРёРј Рё тем же именем, РЅРѕ разным составом параметров. Ртот принцип иллюстрируется РІ упражнении.
Упражнение 5.1 (продолжение)
29. Добавить РІ класс Dog еще РѕРґРёРЅ метод Speak(), объявление которого приведено РІ листинге 5.15. Ртот метод почти ничем РЅРµ отличается РѕС‚ уже существовавшего метода Speak(), РєСЂРѕРјРµ того, что РѕРЅ принимает РІ качестве параметра целое число Рё отображает его значение.
Листинг 5.15
void Speak(int x){
char mm[32];
wchar_t *szStr = L"";
wchar_t mstr[32];
sprintf(mm,"Перегрузка, значение параметра: %d", x);
mbstowcs(mstr, mm, 32);
szStr = mstr;
MessageBox(NULL, szStr, TEXT(В«TUTВ»), 0);
};
30. Теперь нужно переписать обработчик щелчка на кнопке Assign, как показано в листинге 5.16. Листинг 5.16
case IDC_BUTTON3:
Dogs[0]->Speak();
Dogs[0]->Speak(350);
break;
Компиляция и выполнение программы пройдут без ошибок. В C++ для обозначения перегруженных функций не нужны никакие особенные директивы. Компилятор, встретив функции с одинаковыми именами, но разным составом параметров, сам понимает, что они перегружены, и во время вызова функции именно по параметрам определяет, какую именно из перегруженных функций надо вызывать.
Приведение типов
В C++ есть два способа приведения типов, заимствованных из C. Можно использовать «тихое» приведение типов, когда разрядность приводимого типа меньше или равна разрядности типа, к которому осуществляется приведение. В этом случае потери информации не происходит, и приведение может быть осуществлено в момент присваивания, без применения особых операторов. Следующий фрагмент кода демонстрирует работу подобного приведения типа.
byte x = 12; float y = x;
Также можно использовать явное приведение типов. Оно позволяет приводить один тип к другому при возможности потери или искажения информации. В этом случае ответственность за возможную потерю информации перекладывается на плечи программиста. Явное приведение типов выполняется при помощи оператора (). Следующий фрагмент кода демонстрирует его использование.