Однако в этой программе есть один небольшой недостаток: классы Savings и Checking имеют очень много общего, и хотелось бы найти возможность уменьшить количество повторений кода. Эта возможность реализована в очередной версии нашей программы — BUDGET3.
Здесь продолжается преобразование исключительно функциональной версии программы BUDGET1, которая затем прошла через объектно-основанный этап своей эволюции — BUDGET2, в объектно-ориентированную программу BUDGET3.
_________________
355 стр. Глава 31. Программа BUDGET

«В этой программе использованы концепции, представленные в четвёртой частикниги.»
[ Помни! ]
Программа осуществляет вложение денег на счёт и снятие со счёта в воображаемом банке. Пользователь поочередно вводит номера банковских счетов и суммы вкладов на этот счёт и снятий с него. После того как пользователь выполнил все транзакции, программа показывает баланс каждого счёта и общий баланс. Обе программы — BUDGET2 и BUDGET3 — эмулируют Checking ( чековый ) и Savings ( сберегательный ) счета. Чековые счета взимают небольшой гонорар за обслуживание при каждом снятии, если баланс упал ниже 500 долларов, тогда как сберегательный счёт взимает большой гонорар за обслуживание при первом снятии, независимо от баланса.
Программа BUDGET2 превосходит BUDGET1 только в одном: она изолирует особенности классов, описывающих счёт, от внешних функций, которые манипулировали счетами. К сожалению, BUDGET2 содержала большое количество дублированного кода в классах Savings и Checking , и именно от него мы и хотим избавиться, используя принципы наследования.
Программа BUDGET3 вносит новые улучшения. С помощью такого "супергероя" объектно-ориентированного программирования, как наследование, и его верного бокового удара — полиморфизма мы смогли оптимизировать два класса счетов, объединив в один класс Account всё то общее, что присуще этим двум классам, и получив в результате меньшее и более компактное множество классов.
Кроме того, вместо массивов в программе используется связанный список для хранения объектов Account , что снимает ограничение на количество счетов, присущее более ранним версиям программы. Кроме того, код программы разделён на модули с различными пространствами имён .
Реализация модуля со связанным списком...356
Основное ограничение, присущее первым двум версиям программы, заключается в том, что они обе используют для хранения счетов массивы фиксированного размера, так что количество счетов, которые эти программы могут обработать, изначально ограничено. Более разумное решение состоит в использовании связанных списков объектов. Проблема лишь в том, что связанные списки ничего не знают о банковских счетах.
Очевидно, что можно разделить концепцию связанных списков на два класса. Этот тип разделения хотя и отличен от рассматриваемого в книге, но не менее важен. Он разносит классы с отношением СОДЕРЖИТ в различные файлы.

«Контейнер ( такой как массив или связанный список ) СОДЕРЖИТ счета.»
[ Помни! ]
Интерфейс соответствующего класса определён в заголовочном файле AccountLinkedList.h
/* AccountLinkedList — поддерживает связанный */
/* список объектов Account */
#ifndef _ACCOUNTLINKEDLIST_
#define _ACCOUNTLINKEDLIST_
/* Данное предварительное объявление — неприятное следствие того, что Account не является частью пространства имён */
_________________
356 стр. Часть 6. Великолепная десятка
/* Lists. Этой неприятности мы сумеем избежать в следующей версии программы */
class Account ;
namespace Lists
{
/* Предварительное объявление классов */
class AccountLinkedList ;
class Node ;
/* LinkedList — связанный список объектов Node */
class AccountLinkedList
{
public :
AccountLinkedList( ) { pHead = 0 ; }
void addNode( Node* pNode ) ;
Node* firstNode( ) { return pHead ; }
protected :
Node* pHead ;
} ;
/* Node — узел в связанном списке, указывающий на объект Account */
class Node
{
friend class AccountLinkedList ;
public :
Node( AccountLinkedList* pL , Account* pAcc )
{
pList = pL ;
pNext = 0 ;
pAccount = pAcc ;
pL -> addNode( this ) ;
Читать дальше