|
Программирование >> Поддержка объектно-ориентированного программирования
: public virtual window, public window w input, public window w menu void draw(); void get input(); В этом классе window w input and menu::get input() будет переопределять все функции get input(). Подробно механизм разрешения неоднозначности описан в $$R.10.1.1. 6.6 Контроль доступа Член класса может быть частным (private), защищенным (protected) или общим (public): Частный член класса X могут использовать только функции-члены и друзья класса X. Защищенный член класса X могут использовать только функции-члены и друзья класса X, а так же функции-члены и друзья всех производных от X классов (см. $$5.4.1). Общий член можно использовать в любой функции. Эти правила соответствуют делению обращающихся к классу функций на три вида: функции, реализующие класс (его друзья и члены), функции, реализующие производный класс (друзья и члены производного класса) и все остальные функции. Контроль доступа применяется единообразно ко всем именам. На контроль доступа не влияет, какую именно сущность обозначает имя. Это означает, что частными могут быть функции-члены, константы и т. д. наравне с частными членами, представляющими данные: class X { private: enum { A, B }; void f(int); int a; void X::f(int i) if (i<A) f(i+B); a + +; void g(X& x) int i = X::A; ошибка: X::A частный член x.f(2); ошибка: X::f частный член x.a++; ошибка: X::a частный член 6.6.1 Защищенные члены Дадим пример защищенных членов, вернувшись к классу window из предыдущего раздела. Здесь функции draw() предназначались только для использования в производных классах, поскольку предоставляли неполный набор возможностей, а поэтому не были достаточны удобны и надежны для общего применения. Они были как бы строительным материалом для более развитых функций. С другой стороны, функции draw() предназначались для общего применения. Это различие можно выразить, разбив интерфейсы классов window на две части - защищенный интерфейс и общий интерфейс: protected: void draw(); другие функции, private: представление класса служащие строительн1м материалом и в производных классах, таких, как window w border или Такое разбиение можно проводить window w menu. Префикс используется в именах защищенных функций, являющихся частью реализации класса, по общему правилу: имена, начинающиеся с , не должны присутствовать в частях программы, открытых для общего использования. Имен, начинающихся с двойного символа подчеркивания, лучше вообще избегать (даже для членов). Вот менее практичный, но более подробный пример: class X { по умолчанию частная часть класса int priv; protected: int prot; public: int publ; void m(); Для члена X::m доступ к членам класса неограничен: void X::m() priv = 1; prot = 2; publ = 3; нормально нормально нормально Член производного класса имеет доступ только к общим и защищенным членам: class Y : public X { void mderived(); Y::mderived() priv prot 1; 2; publ = 3;
ошибка: priv частный член нормально: prot защищенный член, а mderived() член производного класса Y нормально: publ общий член В глобальной функции доступны только общие члены: void f(Y* p) p->priv = 1; p->prot = 2; p->publ = 3; частный член защищенный член, а f() ошибка: priv ошибка: prot не друг или член классов X и нормально: publ общий член class window { public: virtual void draw(); class Y1 : public X { }; class Y2 : protected X { }; class Y3 : private X { }; Поскольку X - общий базовый класс для Y1, в любой функции, если есть необходимость, можно (неявно) преобразовать Y1* в X*, и притом в ней будут доступны общие члены класса X: void f(Y1* py1, Y2* py2, Y3* py3) ошибка: X ошибка ошибка: X ошибка
( - общий базовый класс Y1 защищенный базовый класс Y2 частный базовый класс Y3 Теперь пусть описаны class Y2 : protected X { }; class Z2 : public Y2 { void f(); }; Поскольку X - защищенный базовый класс Y2, только друзья и члены Y2, а также друзья и члены любых производных от Y2 классов (в частности Z2) могут при необходимости преобразовывать (неявно) Y2* в X*. Кроме того они могут обращаться к общим и защищенным членам класса X: void Z2::f(Y1* py1, Y2* py2, Y3* py3) X* px = py1; py1->a = 7; px = py2; py2->a = 7; px = py3; py3->a = 7; общий базовый класс Y1 нормально: X нормально нормально: X - защищенный базовый класс Y2, а Z2 - производный класс Y2 нормально ошибка: X - частный базовый класс Y3 ошибка Наконец, рассмотрим: class Y3 : private X { void f(); }; Поскольку X - частный базовый класс Y3, только друзья и члены Y3 могут при необходимости преобразовывать (неявно) Y3* в X*. Кроме того они могут обращаться к общим и защищенным членам класса X: void Y3::f(Y1* py1, Y2* py2, Y3* py3) X* px = py1; py1->a = 7; px = py2; py2->a = 7; px = py3; py3->a = 7; нормально общий базовый класс Y1 нормально: X нормально ошибка: X - защищенный базовый класс ошибка нормально: X - частный базовый класс Y3, а Y3::f член Y3 6.6.2 Доступ к базовым классам Подобно члену базовый класс можно описать как частный, защищенный или общий: class X { public: int a;
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |