Программирование >>  Поддержка объектно-ориентированного программирования 

1 ... 51 52 53 [ 54 ] 55 56 57 ... 120


: 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 ошибка

X* px = py1;

py1->a = 7;

px = py2;

py2->a = 7;

px = py3;

py3->a = 7;

( - общий базовый класс 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;



1 ... 51 52 53 [ 54 ] 55 56 57 ... 120

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика