Void show ()
...
int Func (char*);
};
class C: public A { // С – также абстрактный класс
void F ();
};
- Абстрактные классы предназначены для представления общих понятий, которые предстоит конкретизировать. На базе общих понятий строятся частные производные классы для описания конкретных объектов.
- Абстрактный класс может иметь явно определенный конструктор.
- Если все -таки предстоит создавать самостоятельные объекты базового класса, то исходные виртуальные функции следует определять не как чистую, а как пустую.
Рассмотрим программу, в которой на основе базового класса point построен абстрактный класс figure.
В классе figure определены конструктор и чистая виртуальная функция для вывода изображения фигуры на экран show().
Однако реальное выполнение show() возможно только после создания производного класса, в котором чистая виртуальная функция будет заменена компонентной функцией show() для конкретной фигуры.
Кроме того, класс figure включает еще функции hide() – для удаления изображениефигуры и move() – для передвижения фигуры. Обе функции вызывают в своем теле чистую виртуальную функцию show().
// figure.cpp
#include “point.cpp”
class figure: public point {
public:
figure (point p): point (p. GetX(), p. GetY ()) { } // конструктор
virtual void show () =0; // функция для определения в производных классах
void hide()
{int a,b;
a=getcolor();
b= getbkcolor();
setcolor(b);
show();
setcolor(a);
}
void move (point p)
{ hide(); x = p.GetX(); y= p.GetY(); show ();}
};
class ellips: public figure {
int rx, ry;
public:
ellips (point p, int rxi, int ryi): figure (p)
{ rx = rxi; ry = ryi; }
{ ellipse(x, y, 0, 360, rx, ry); }
};
class circ: public figure {
int rad;
public:
circ (point p, int ri): figure (p)
{ rad = ri; }
{ circle(x, y, rad); }
};
// программа
#include <graphics.h>
#include “figure.cpp”
#include<conio.h>
void main ()
{point A (100, 80), B (300, 200); // создает два экземпляра “точки”
circ C (A, 60); // создаем окружность с центром в т. А и радиусом 60 пикселей
ellips E (B, 200, 100); // создаем эллипс с центром в т. В и радиусами 200 и 100 пикселей
// инициируем графику
int d = DETECT, m;
initgraph(&d, &m, “ d:\\borlandc\\ bgi”);
A.show(); getch();
B.show(); getch();
C.show(); getch();
E.show(); getch();
C.move(B); getch();
E.hide(); getch();
C.hide();getch();
closegraph ();
}
Рассмотрим пример использования виртуальных функций и указателя на базовый класс:
//замещение функций базового класса Button - кнопка
#include <conio.h>
#include <graphics.h>
const int width = 50; //ширина кнопки
const int height = 70; //высота кнопки
const int faset = 5;
class screen { // класс инициализации графического режима
public:
screen () { // конструктор - переход в графический режим
int d =DETECT, m;
initgraph (&d, &m, "D:\\borlandc\\bgi");
setfillstyle (1, DARKGRAY); // заливка сплошная темно-серым цветом
floodfill (3,5, WHITE);
// заполнить весь экран темно-серым цветом и обвести границу
//белым
}
~screen() {closegraph(); } // деструктор - переход в текстовой режим
};
class Button { //базовый класс
protected:
int x, y; // координаты кнопки верхнего угла кнопки
public:
Button (int xi, int yi) { x= xi; y= yi; draw();}
void draw(); // две перегруженных функции: 1- рисование кнопки
void draw(char*s)
// 2 - функция вывода строки в центре кнопки черным цветом
{ setcolor (BLACK);
outtextxy(x+width/2, y+height/2, s);
// посередине выводится слово черным цветом
setcolor(WHITE); // установка белого цвета символов
}
virtual void action () =0; // чистая виртуальная функция
virtual int selected (char) =0; // чистая виртуальная функция
};
//компонентная функция рисования кнопки
void Button:: draw()
{
setfillstyle(1, LIGHTGRAY); // заливка сплошным светло серым цветом
bar3d(x,y, x+width, y+height,0,0); // вычерчивается трехмерное изображение
//параллелепипеда и закрашивается его передняя грань
rectangle(x+faset, y+ faset, x+width -faset, y+height- faset); // вычерчивает белымцветом //прямоугольник внутри
moveto(x, y);
lineto(x+faset, y+faset); // скос кнопки
moveto(x+width,y);
lineto(x+width-faset, y+faset); // скос кнопки
moveto(x,y +height);
lineto(x+faset, y+height-faset); // скос кнопки
moveto(x+width,y +height);
lineto(x+width-faset, y+height-faset); // скос кнопки
setfillstyle(1, DARKGRAY); // цвет заливки темно- серый
floodfill(x+width-3,y+10,WHITE); // заполнить замкнутую фигуру темно-серым цветом,
// очертить границу фигуры белым цветом
floodfill(x+10,y+height-3,WHITE);
}
class Button1:public Button // производный класс – кнопка с номером
{
public:
Button1(int xi, int yi): Button(xi,yi) { draw("1");}
void virtual action ();
int selected (char c);
};
void Button1:: action () // функция обработки нажатия на кнопку
{
bar (10,100,150,110); // заполняет цветом заливки область, не обводя ее,
// используется, чтобы стереть предыдущую надпись
outtextxy(10,100,"Pressed button 1"); // выводится надпись
}
int Button1::selected (char c)
{return (c= ='1');}
class Button2:public Button {
public:
Button2(int xi, int yi): Button(xi,yi) { draw("2");}
void action ();
int selected (char c);
};
void Button2::action ()
{bar (10,100,150,110);
outtextxy(10,100,"Pressed button 2"); }
int Button2::selected (char c)
{return((c=='2')?1:0);}
class Button3:public Button {
public:
Button3(int xi, int yi): Button(xi,yi) { draw("3");}
void action ();
int selected (char c);
};
void Button3:: action ()
{bar (10,100,150,110);
outtextxy(10,100,"Pressed button 3");}
int Button3::selected (char c)
{return (c=='3');}
class Button4:public Button {
public:
Button4(int xi, int yi): Button(xi,yi) { draw("4");}
void action ();
int selected (char c);
};
void Button4::action ()
{bar (10,100,150,110);
outtextxy(10,100,"Pressed button 4");}
int Button4::selected (char c)
{return (c=='4');}
void main () {
screen n; // создается объект графический экран
Button*bt[4]; // объявлен массив указателей на базовый класс
// создается четыре объекта производных классов,
// адреса участков памяти под объекты присвоены указателям на базовый класс
bt[0]=new Button1(10,10);
bt[1]=new Button2(65,10);
bt[2]=new Button3(120,10);
bt[3]=new Button4(175,10);
char c;
c=getch();
while(c>='1'&& c<='4')
{
for(int i =0; i<4; i++) // организуем цикл по массиву указателей
if(bt[i]->selected(c)) // Если функция selected() возвращает“истину”
//то вызывается для данного объекта функция action()
bt[i] ->action();
c=getch();
}
}