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

1 ... 74 75 76 [ 77 ] 78 79 80 ... 108


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

указатель не такая уж большая цена безопасной работы программы.

Лучше всегда объявлять деструкторы виртуальными, даже если ваш класс не наследуется (пока не наследуется!): ведь никогда не известно, в какой момент появится некто (может, это будете вы сами), желающий

воспользоваться вашим классом как базовым для своего собственного класса. Если вы не объявили деструктор виртуальным, обязательно документируйте это!




Гл 23

Разложение классов

в э/ной главе...

V Разложение

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

У Рационализация бюджета: BUDGET3,CPP

наследования позволяет классу наследовать свойства базового класса. # V Наследование помогает в достижении многих целей; например, благодаря ему я плачу за обучение моего сына. Оно помогает избежать повторения кода и сократить время, затрачиваемое на написание программ. Благодаря наследованию можно повторно использовать уже существующий код в новых программах, переопределяя функции.

Главное преимущество наследования - возможность указывать тип взаимосвязи между классами. Это так называемая взаимосвязь типа ЯВЛЯЕТСЯ: микроволновая печь ЯВЛЯЕТСЯ печью и т. д.

Разложение - это прекрасный способ создания правильных связей. К примеру, связь микроволновой печи с конвекционной печью кажется естественной. Утверждение же о том, что микроволновая печь является особым типом тостера, скорее всего, вас несколько насторожит. Конечно, оба эти прибора нагревают, оба используют электричество и оба находятся на кухне, но на этом сходство заканчивается - микроволновая печь не готовит тосты.

Процедура определения классов, свойственных данной проблеме, и задания корректных связей между этими классами известна под названием разложение (factoring)

(это слово относится к арифметике, с которой вы мучились в средней школе; помните, как вы занимались разложением числа на простые множители: 12 равно 2, умноженное на 2 и на 3...).

Чтобы как работает разложение, вернемся назад и посмотрим на классы

Checking и Savings, использованные в программе BUDGET, которая приводится в конце каждой части. Я мог бы до посинения рассказывать об этих классах, однако, к счастью, объектно-ориентированные программисты придумали довольно наглядный и краткий путь описания классов. Классы Checking и Savings показаны на рис. 23.1.

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

) У Большой прямоугольник - это класс. Имя класса написано сверху.

Имена в меньших прямоугольниках - это функции-члены. Имена не в прямоугольниках - это данные-члены. / Имена, которые выступают за пределы прямоугольника, ограничивающего

класс, являются открытыми; к этим членам могут обращаться функции, не 1 являющиеся членами класса или его наследников. Члены, которые нахо- дягся полностью внутри прямоугольника, недоступны снаружи класса. Толстая стрелка обозначает связь типа ЯВЛЯЕТСЯ. is Тонкая стрелка обозначает связь типа СОДЕРЖИТ.



Chec

pRrst

Count

ГИЧ)

I fftArouritsO I

accountNumber

balance

j\/\№/\£<)3

accountNoO

mi-1 oart ,

---aKmNrrte

LnoteciWiitelU ncWrtMraNals

Рыс. Независимые классы Checking и Savings

<$! Автомобиль ЯВЛЯЕТСЯ транспортным средством СОДЕРЖИТ мотор.


при этом

На рис. 23.1 вы можете увидеть, что класс king и Savings имеют много общего. Например, оба класса включают фупкции-члепы withdrawal (} и deposit (). Поскольку эти классы не идентичны, они, конечно же, должны оставаться раздельными (в реальном банковском приложении эти два класса отличались

бы гораздо существеннее). Однако мы должны найти способ избежать дублирования.

Можпо сделать так, чтобы один из этих классов наследовал другой. Класс Savings имеет больще членов, чем Checking, так что мы могли бы унаследовать Savings от Checliing. Такой путь реализации этих классов приведен на рис. 23.2. Класс Savings наследует все члены класса Checking. Кроме того, в классе добавлен член noWithdrawal и переопределена функция withdrawal (). Эта функция нереонределена, поскольку правила снятия денег со сберегательного счета отличаются от правил снятия с чекового

счета (хотя меня эти правила вообще

Checking

MidrawaJp

Ideposit;) cC3cOinlNo(H pi-ret

LnextiL

\ noAccountsO [

accoinNimber balance

Savings

I уДх1галй1!)] ncWrttvdiaws

Рис. 23.2. Класс Savings реализован как подкласс Checking

не поскольку у меня нет де-

нег, которые можно было бы снять со счета).

Хотя наследование Savings от Checking и сберегает наш труд, нас оно не очень удовлетворяет. Главная проблема состоит в том, что оно искажает истинное положение вещей. При таком использовании наследования подразумевается, что счет Savings является снециальпым случаем счета Checking.

Ну и что - скажете вы. - Такое наследование работает и сохраняет нам силы и время . Это, конечно, так, но мои предупреждения - это не просто сотря-сание воздуха. Такие искажения запутывают программиста уже и сейчас, но еще больще будут мещать в дальнейшем. Однажды программист, не знакомый с нашими приемчиками , будет читать нашу

программу, пытаясь понять, что же она



1 ... 74 75 76 [ 77 ] 78 79 80 ... 108

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