Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
С++ Страуструп.doc
Скачиваний:
4
Добавлен:
18.04.2019
Размер:
2.72 Mб
Скачать

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; // чисто виртуальная функция

};

Класс, в котором есть виртуальные функции, называется абстрактным.

Объекты такого класса создать нельзя:

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.

После введения абстрактного класса у нас есть все основные

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]