Бьерн Страуструп. Язык программирования С++ Второе дополненное издание



Pdf көрінісі
бет121/256
Дата11.07.2022
өлшемі2,87 Mb.
#37591
1   ...   117   118   119   120   121   122   123   124   ...   256
6.3 Абстрактные классы 
Многие классы сходны с классом employee тем, что в них можно дать разумное определение 
виртуальным функциям. Однако, есть и другие классы. Некоторые, например, класс shape
представляют абстрактное понятие (фигура), для которого нельзя создать объекты. Класс shape 
приобретает смысл только как базовый класс в некотором производном классе. Причиной является то, 
что невозможно дать осмысленное определение виртуальных функций класса shape: 
class shape { 
// 
... 
public: 
virtual void rotate(int) { error("shape::rotate"); } 
virtual void draw() { error("shape::draw"): } 
// нельзя ни вращать, ни рисовать абстрактную фигуру 
// 
... 
}; 
Создание объекта типа shape (абстрактной фигуры) законная, хотя совершенно бессмысленная 
операция: 
shape s; // бессмыслица: ``фигура вообще'' 
Она бессмысленна потому, что любая операция с объектом s приведет к ошибке. 
Лучше виртуальные функции класса shape описать как чисто виртуальные. Сделать виртуальную 
функцию чисто виртуальной можно, добавив инициализатор = 0: 
class shape { 
// 
... 
public: 
virtual void rotate(int) = 0; 
// 
чисто виртуальная функция 
virtual void draw() = 0; 
// 
чисто виртуальная функция 


Бьерн Страуструп.
Язык программирования С++ 
 
157 
}; 
Класс, в котором есть виртуальные функции, называется абстрактным. Объекты такого класса создать 
нельзя: 
shape s; // ошибка: переменная абстрактного класса shape 
Абстрактный класс можно использовать только в качестве базового для другого класса: 
class circle : public shape { 
int 
radius; 
public: 
void rotate(int) { } 
// 
нормально: 
// переопределение shape::rotate 
void 
draw(); 
// нормально: 
// 
переопределение shape::draw 
circle(point p, int r); 
}; 
Если чисто виртуальная функция не определяется в производном классе, то она и остается таковой, а 
значит производный класс тоже является абстрактным. При таком подходе можно реализовывать 
классы поэтапно: 
class X { 
public: 
virtual void f() = 0; 
virtual void g() = 0; 
}; 
X b; // ошибка: описание объекта абстрактного класса X 
class Y : public X { 
void f(); // переопределение X::f 
}; 
Y b; // ошибка: описание объекта абстрактного класса Y 
class Z : public Y { 
void g(); // переопределение X::g 
}; 
Z c; // нормально 
Абстрактные классы нужны для задания интерфейса без уточнения каких-либо конкретных деталей 
реализации. Например, в операционной системе детали реализации драйвера устройства можно 
скрыть таким абстрактным классом: 
class character_device { 
public: 
virtual int open() = 0; 
virtual int close(const char*) = 0; 
virtual int read(const char*, int) =0; 
virtual int write(const char*, int) = 0; 
virtual int ioctl(int ...) = 0; 
// 
... 
}; 
Настоящие драйверы будут определяться как производные от класса character_device. 
После введения абстрактного класса у нас есть все основные средства для того, чтобы написать 
законченную программу. 


Бьерн Страуструп.
Язык программирования С++ 
 
158 


Достарыңызбен бөлісу:
1   ...   117   118   119   120   121   122   123   124   ...   256




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет