Программирование >>  Унарные и бинарные операторы 

1 ... 24 25 26 [ 27 ] 28 29 30 ... 37


Листинг 10.2

#1 ncl ude <iostreani> using namespace std: #1nclude matrix3.h #include matrix2 2.h 3x+ 5y=21 lOx-y =17 int main(){

matrix2 2 a(3.5.10.-l);

matrix2 2 xa(21.5.17.-l):

matrix2 2 ya(3.21.10.17):

double x.y:

x=xa.det()/a.det():

y=ya.det()/a.det():

cout X endl: x=2

cout у endl: y=3

return 0:

В ней создаются три показанные ранее матрицы, вычисляются их определители и выводятся на экран значения неизвестных. Включаемый файл matrix3.h представляет собой окончательный вариант класса matrix со всеми конструкторами и оператором присваивания {), а в файле matrix2 2.h хранится описание квадратной матрицы 2x2 (см. листинг 10.1).

Право наследования

Решая систему из двух уравнений, мы не задумывались о том, какие права доступа к переменным, унаследованным от базового класса, будут у класса производного. Ясно, что валить все в кучу нельзя, и то, что было тайным в базовом классе, не может стать явным в производном. Вполне понятно, что переменные из области publ ic базового класса останутся открытыми и в производном. Но для многих будет неожиданным узнать, что переменные из области private базового класса в производном классе окажутся недоступными. Добраться до

Право наследования 1 89

них смогут только собственные функции базового (а теперь уже и производного) класса. Пояснит сказанное пример программы, показарпюй в листинге 10.3. Листинг 10.3

#include <iostream>

using namespace std:

class Base{

public:

int i:

private:

int ak;

class Der : public Base { public:

void geti(){cout i endl:} void getkOJcout к endl:} void fD(Bases. DerS): private: int k:

void Der::fD(Base& b. Der& d){ b.i = 5: d.i = 7:

b.ak = 0: Из класса Der - нельзя

d.k = 11:

d.ak=0: Нельзя!!!

ak=0: Тем более нельзя

int main(){

Base b: Der dl.d2:

cout sizeof(Base) endl:

cout slzeof(Der) endl:

dl.fD(b.d2):

d2.get1(): 7

d2.getk(); 11

return 0:

В этом примере создаются два игрушечных класса - базовый класс Base с двумя переменными i (открытая) и ак (тайная), а также производный класс Der с тайной переменной к. Поскольку Der - производный класс.



public Base {

cout j endl:} cout к endl;}

int ak: }:

class Der public:

void getjO

void getkO

void fD(Base&. DerS); private;

int k:

void Der::fD(Base& b. Der& d){ b.j - 0; j - protected!!! b.ak = 0: ak- private! II If

меняет *this II

d.j = 9: d.k = 11: j=13:

d.ak=0; ak=0; }

int main(){

Base b: Der dl.d2:

b.ak-0:

dl.fD(b.d2):

d2.getj();

d2.getk():

dl.getjO:

return 0;

нельзя

В этой профамме производный класс Der наследует две переменных: j (protected) н ак (private). По-прежнему из производного класса пет доступа к защищетнгым и тайным .элементам базового класса, то есть инструкции Ь. j=0 и Ь.ак=0 внутри функции fD() некорректны. Но теперь производный класс имеет доступ к собственной переменной j, объявленной в базовом классе в области protected, и внутри функции fD() можно записать инструкцию

d.j-9:

Естественно, прои.зводному классу доступны свои тайные переме1П1ые (d.k-0:), но недоступны перемен-

ОН наследует переменные i и ак базового класса. Всего в классе Der окажутся три переменных: i, ак и к. Переменная i, понятное дело, будет доступна и в базовом, и в производном классах, переменная к, номещенн;ш в область private производного класса, будет доступна т производного класса, но не из базового! А вот перемсп-пая ак из области private базового iciacca в прои,звод-JIOM классе будет вообще недоступна. То есть в собственной функции производного класса fd(Base& b. DerS d) запись d. ak=0 иекорректпа, и тем более некорректна запись ак=0! Хоть ак - переменная, принадлежащая loiac-су Der, по в базовом классе она объявлена в области private, а по мнению разработчиков С++ производный класс не может изменить статус тайной переменной даже после того, как она становится его частью. Поэтому производному классу приходится общаться с переменной ак так, как будто она чужая, используя ynacjic-дованные собственные функции базового класса.

Задача 10.1. Чему равны результаты вызовов size-of(Base) и sizeof(Der)?

Итак, производный класс страдает от того, что не имеет прямого доступа к тем своим переменным, которые noMCHiCHbi в область private базового класса. Чтобы частично восстановить справедливоегь , создатели С++ пpидyмaJПI ключевое слово protected (saninnien-ный),делаюн1ее переменные доступными как базовому, так и производному классам, причем для всего остального мира они остаются закрытыми (private). Программа, показанная в листинге 10.4, содержит чуть измененные базовый (Base) и производный (Der) классы.

Листинг 10.4

include <iostream> using namespace std; class Base { protected: int j: private:



Изменчивость и отбор 193

using namespace std: class point{ public:

pointCdouble xc. double yc): x(xc).y(yc){} void show(){

cout ( X . у ) endl: }

protected: double x: double y:

class cpoint:public point { public:

cpoint (double xc. double yc, string s):

point(xc.yc).coUs){} void show(){

cout ( X , у )

cout col endl: }

protected: string col:

int main(){ point p(2.3): cpoint cp(4.5. red ): p.showO: (2.3) cp.showO: (4.5) red return 0: }

Функции, выводящие на экран характеристики объектов, названы в обоих классах одинаково - showO, но путаницы не возникает, потому что инструкция ср. show() вызывает функцию производного класса, а инструкция р.ShowO - соответствующую функцию базового класса point.

Замечу, что в одинаковых названиях похожих функций производного и базового классов есть большой смысл, ведь объекты этих классов довольно близки, и можно представить их смесь , где для каждого из объектов вызывается своя функция showO.

ные из области private базового класса (некорректна инструкция d.ak-0:). Заметим, что инструкция j=13 относится к текущему объекту производного класса. Раз эта функция вызывается у нас как dl .fD(b.d2), то текущим будет объект dl, и переменная dl. j станет равной 13. А одноименная переменная объекта d2 будет равна 11.

Изменчивость и отбор

До сих пор мы изучали только наследование данных, считая вопросы наследования собственных функций понятными и естественными. Например, в разделе Составные объекты класс matrix2 2 без труда использовал оператор доступа () базового класса.

Но вышло так потому, что оператор О работает с теми же датншми, что и в базовом классе. Все оказывается иначе, когда унаследованной собственной функции требуются новые данные из производного класса.

Для примера рассмотрим класс point, описывающий точку на плоскости. У этого класса есть собственная функция show(), показывающая на экране значения двух координат. Предположим теперь, что нам понадобилось описание цветной точки на плоскости. Соответствующий класс cpci nt разумно сделать производным от класса обычной точки, добавив еще одну переменную, хранящую значение цвета. Но тогда функция show() базового класса не сможет вывести на экран цвет точки, потому что ничего о нем не знает. Придется в классе cpoint создать новую функцию, выводящую на экран не только координаты, но и цвет точки. Программа, где созданы два класса: point (точка) и cpoint (цветная точка), показана в листинге 10.5.

Листинг 10.5

#include <iostream> #include <string>



1 ... 24 25 26 [ 27 ] 28 29 30 ... 37

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