Программирование >>  Аргументация конструирования 

1 ... 76 77 78 [ 79 ] 80 81 82 ... 108


Концепция абстрактных классов

Абстрактный класс- это класс с одной ил лес чисто виртуальной функцией. Прекрасно, это все разъясняет...

Ну хорошо, чисто виртуальная функция - это функция-член без тела функции (которого нет. например, потому, что никто не знает, как реализовать это самое тело).

Бессмысленно спрашивать о том, каким должно быть тело функции withdrawal () в классе Account. Хотя, конечно, сама концепция снятия денег со счета имеет смысл. Программист на C++ может написать функцию withdrawal (), которая будет отражать концепцию снятия денег со счета, но при этом данная функция не будет иметь тела, поскольку мы не знаем, как ее реализовать. Такая функция называется чисто виртуальной (не спрашивайте меня, откуда взялось это название).

Синтаксис объявления чисто виртуальной функции показан в приведенном ниже классе Account.

Account - это абстрактный класс

class Account

protected:

Account(Accounts с) ; public:

Account(unsigned accNo, float initialBalance = O.OF);

unsigned int accountNoO; float acntBalance(} ; static Account *first(}; Account *next () ; static int noAccounts0;

функции транзакций void deposit();

приведенная ниже функция является чисто

virtual void withdrawal(float amount) = 0;

protected:

если хранить счета в связанное ске, не будет ограничение на их количество static Account *pFirst; Account *pNext;

static int count; количество счетов unsigned accountNumber;

float balance;

Наличие после объявления функции (} символов 0 показывает, что

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

функцию более конкретно.

Вообще говоря, чисто виртуальная функция может иметь тело, но обсуждение этого вопроса выходит за рамки данной книги. - Прим. ред.




Я считаю это объяснение глупым, и мне оно нравится не более чем вам, так что просто выучите и живите с ним. Для этого объяснения есть причина, если не оправдание. Каждая виртуальная функция должна иметь свою ячейку в специальной таблице, в которой содержится адрес функции. Так вот: ячейка для чисто виртуальной функции

содержит ноль.

Абстрактный класс не может быть реализован; другими мами, вы не можете

создать объект абстрактного класса. Например, приведенное ниже объявление некорректно.

void fn() f

Account acnt(1234,100.00); это некорректно

acnt.withdrawal(50); куда, по-вашему, должен

обращаться этот вызов?

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

Account: : withdrawal О не существует.

Абстрактные классы служат базой для других классов. Account содержит универсальные свойства для всех банковских счетов. Вы можете создать другие типы банковских счетов, наследуя класс Account, но сам этот класс не может быть реализован.

Создание полноценного класса из абстрактного

Подкласс абстрактного класса остается абстрактным, пока в нем не переопределены все чисто виртуальные функции. Класс Savings не является абстрактным, поскольку переопределяет чисто виртуальную функцию withdrawal () совершенно реальной. Объект класса Savings отлично знает, как реализовать функцию

() и куда обращаться при ее вызове. То же касается и класса он не виртуальный, поскольку withdrawal () переопределяет чисто виртуальную функцию, определенную ранее в базовом классе.

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

class Display

public:

virtual void initialize () = 0; virtual void write(char *pString) = 0;

); {

сделаем обе функции-члена реальныьм

virtual void initialize!) ;

virtual void write (char *pString) ;

clas /GA : public Display {

пеоеопределим только одну функцию



pstring);

(Uses ЧзЗКА : xiUlc HiKA vijXBl \id initialize;

все остальное

Класс Display, описывающий дисплеи персонального компьютера, содержит две чисто виртуальные функции: initialize () и writef]. Вы не можете ввести эти функции в общем виде. Разные типы видеоадаптеров инициализируются и осуществляют вывод по-разному.

Один из подклассов - S\CA - пе абстрактный. Это отдельный тип видеоадаптера, и программист точно знает, как его реализовать. Таким образом, класс SVGA переопределяет обе функции- initialized и write () - именно так, как необходимо для данного адаптера.

Еще один подкласс - HWVGA . Программисту известно, как программировать ускоренный VGA-адаптер. Поэтому между общим классом Display и его частным случаем, ThreedVGA, который представляет собой специальный тип карт 3-D, находится

еще один уровень абстракции.

В нашем обсуждении предположим, что запись во все аппаратно ускоренные карты VGA происходит одинаково (это не соответствует истине, но представим что это так). Чтобы правильно выразить общее свойство записи, вводится класс реализующий функцию write() (и другие общие для HWVGA свойства). При этом функция initialize () не переопределяется, поскольку для разных типов карт HWVGA она реализуется по-разному.

Поэтому, несмотря на то что функция write () переопределена в классе HWVGA, ОН все равно остается абстрактным, поскольку функция initialize () все еще не переопределена.

Поскольку ThreedVGA наследуется от он переопределить только

одну функцию, initialize {), для того чтобы окончательно определить адаптер дисплея. Таким образом, функция f n () может свободно реализовать и использовать объект класса ThreedVGA.

Замещение нормальной функцией последней чисто виртуальной функции делает класс завершенным (т.е. неабстрактным). Только неабстрактные

классы могут быть реализованы в виде объектов.

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




1 ... 76 77 78 [ 79 ] 80 81 82 ... 108

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