Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по прогр.ч.2.doc
Скачиваний:
3
Добавлен:
01.05.2025
Размер:
293.89 Кб
Скачать

Лекция 8

Конструкторы при наследовании классов

В языке С++ как базовый, так и производный классы могут иметь конструкторы. Конструктор базового класса создает часть объекта, соответствующую базовому классу, а конструктор производного класса _ часть объекта, соответствующую производному классу.

Если конструктор определен только в производном классе, то он создает объект производного класса. Часть объекта, соответствующую базовому классу, создает конструктор по умолчанию.

Рассмотрим пример использования конструктора только в производном классе.

Включим в класс TR предыдущего примера конструктор.

class TR:public GEOM

{public:

char type_tr[80];//тип треугольника

TR(char *st, double a,double b)//конструктор

{setw(a);

seth(b);

strcpy(type_tr,st);

}

double area()

{return getw()*geth()/2;}

void showtype()

{cout<<type_tr<<’\n’;}

};

Главная функция в этом примере может выглядеть так:

void main()

{ TR t(“равнобедренный”,4.0.4.0);;

cout<<”Информация о треугольнике:\n”;

t.showtype();//метод производного класса

t.show();//метод базового класса

cout<<”Площадь=”<<t.area()<<’\n’;

}

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

Определение конструктора производного класса выглядит так:

<имя производного класса>(<список параметров>):<имя базового класса>(<список значений>)

{<тело конструктора производного класса>}

Предположим, что в базовом классе GEOM есть конструктор:

GEOM(double a, double b)

{w=a;

h=b;

}

Тогда конструктор производного класса TR выглядит так:

TR(char *st, double a, double b):

GEOM(a,b)

{strcpy(type_tr,st);}

Здесь конструктор TR вызывает конструктор GEOM с параметрами a и b, который инициализирует поля w и h , а затем инициализирует свое поле type_tr.

Рассмотрим пример.

Построить иерархию классов “точка-окружность” на языке С++. Пусть базовый класс point включает координаты точки , конструктор, функцию рисования точки на экране и функцию гашения точки. Пусть производный класс circ содержит радиус окружности, конструктор, функцию рисования окружности и функцию гашения окружности.

#include<conio.h>

#include<graphics.h>

class point

{protected:

int x,y;

public:

point(int xi,int yi)

{x=xi;y=yi;}

void show()

{putpixel(x,y,getcolor());}

void hide()

{putpixel(x,y,getbkcolor());}

};

class circ: public point

{protected:

int radius;

public:

circ(int xi,int yi,int ri):point(xi,yi)

{radius=ri;}

void show()

{circle(x,y,radius);}

void hide()

{int bk=getbkcolor();

int cc=getcolor();

setcolor(bk);

circle(x,y,radius);

setcolor(cc);

}

};

void main()

{int dr=DETECT;int dm;

initgraph(&dr,&dm,"c:\\BORLANDC\\BGI");

circ a(200,50,20);

circ d(500,200,30);

a.show();

getch();

d.show();

getch();

closegraph();

}

Множественное наследование

В языке С++ допускается множественное наследование- возможность создавать производные классы на основе нескольких базовых классов.

В этом случае производный класс определяется следующим образом:

class <имя производного класса>:

<спецификатор><имя базового класса 1>,

<спецификатор><имя базового класса 2>,

<спецификатор><имя базового класса k>

{<список элементов производного класса>};

Рассмотрим пример. Задан производный класс D, который наследует элементы двух базовых классов B1 и B2.

#include <iostream.h>

class B1

{ protected:

int x;

public:

void showx()

{cout<<x<<’\n’;}

};

class B2

{ protected:

int y;

public:

void showy()

{cout<<y<<’\n’;}

};

class D: public B1, public B2

{public:

void setxy(int i, int j)

{x=i; y=j;}

};

void main()

{D object;

object.setxy(10,20);// элемент производного класса D

object.showx();// элемент базового класса B1

object.showy();// элемент базового класса B2

}

Замечания.

  1. При создании объекта производного класса сначала вызывается конструктор базового класса, а за ним конструктор производного класса.

  2. При разрушении объекта производного класса сначала вызывается его деструктор, а за ним деструктор базового класса.

  3. Если производный класс наследует несколько базовых классов, то вызов конструкторов базовых классов, заданных в списке наследования, происходит слева – направо, а вызов деструкторов – справа – налево.

Например:

class D: public B1, public B2 {//элементы класса D};

Конструкторы: B1, B2, D.

Деструкторы: D, B2, B1.

4.При множественном наследовании никакой класс не может больше одного раза использоваться в качестве непосредственного базового.

Рассмотрим пример множественного наследования.

Задан производный класс, характеризующий окружность, вписанную в квадрат. Этот класс наследует свойства двух базовых классов, определяющих окружность и квадрат.

#include<conio.h>

#include<graphics.h>

class circ

{

int xc,yc,rc;

public:

circ(int xi, int yi, int ri)

{xc=xi;yc=yi;rc=ri;}

void draw()

{circle(xc, yc, rc);}//рисование окружности на экране

void hide()//гашение окружности

{ int bk, cc;

bk=getbkcolor();//возвращает цвет фона

cc=getcolor();//возвращает цвет изображения

setcolor(bk);

circle(xc,yc,rc);

setcolor(cc);//восстанавливает цвет изображения

}

};

class square

{

int xs,ys,ls;

public:

square(int xi, int yi, int li)

{xs=xi;ys=yi;ls=li;}

void drawsquare()

{ int d=ls/2;

line(xs-d,ys-d,xs+d,ys-d);

line(xs-d,ys+d,xs+d,ys+d);

line(xs-d,ys-d,xs-d,ys+d);

line(xs+d,ys-d,xs+d,ys+d);

}

void draw()

{drawsquare();}

void hide()

{int cc;

cc=getcolor();

setcolor(getbkcolor());

drawsquare();

setcolor(cc);

}

};

class circsquare: public circ, public square

{public:

circsquare(int xi,int yi,int ri):

circ(xi,yi,ri),

square(xi,yi,2*ri)

{}

void draw()

{circ::draw();

square::draw();

}

void hide()

{square::hide();

circ::hide();

}

};

void main()

{clrscr();

int dr=DETECT;

int dm;

initgraph(&dr,&dm,"C:\\BORLANDC\\BGI");

circsquare A(100,100,60);

circsquare B(400,300,50);

A.draw();

getch();

B.draw();

getch();

B.hide();

getch();

A.hide();

getch();

closegraph();

}