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

We use cookies. Read the Privacy and Cookie Policy

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

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

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

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

    /* Account — это абстрактный класс */

    class Account

    {

    protected :

        Account( Account& с ) ;

    public :

        Account( unsigned accNo , float initialBalance = 0.0F ) ;

        /* Функции доступа */

        unsigned int accountNo( ) ;

        float acntBalance( ) ;

        static int noAccounts( ) ;

        static Account *first( ) ;  

        Account *next( ) ;

        /* Функции транзакций */

        void deposit( ) ;

        /* Приведённая ниже функция является чисто виртуальной */

        virtual void withdrawal( float amount ) = 0 ;

    protected :

        /* Если хранить счета в связанном списке, не будет ограничения на их количество */

        static Account *pFirst ;

        Account *pNext ;

        static int count ; /* Количество счетов */

        unsigned accountNumber ;

        float balance ;

    } ;

______________

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

_________________

254 стр. Часть 4. Наследование

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

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

[Технические подробности]

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

    void fn( )

    {

        Account acnt( 1234, 100.00 ) ; /* Это некорректно */

        acnt.withdrawal( 50 ) ; /* Куда, по-вашему, должен обращаться этот вызов? */

    }

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

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