list< AccountPtr > listAccounts ;
/* Чтение пользовательского ввода */
getAccounts( listAccounts ) ;
/* Вывод связанного списка */
displayResults( listAccounts ) ;
/* Пауза для того, чтобы посмотреть на результат работы программы */
system( "PAUSE" ) ; return 0 ;
}
/* getAccounts — загрузка массива счетов */
void getAccounts( list< AccountPtr > & accList )
{
AccountPtr pA ;
/* Цикл, пока не введено 'X' или 'х' */
char accountType ; /* S or С */
while ( true )
{
cout << "Введите S для сберегательного счёта,\n"
<< "С для чекового, X для выхода: " ;
cin >> accountType ;
switch ( accountType )
{
case 'c' :
case 'C' :
pA = new Checking( getAccntNo( ) ) ;
break ;
case 's' :
case 'S' :
pA = new Savings( getAccntNo( ) ) ;
break ;
case 'x' :
case 'X' :
return ;
default :
cout << "Неверный ввод.\n" ;
}
/* Обработка вновь созданного объекта */
accList.push_back( pA ) ;
process( pA ) ;
}
}
_________________
376 стр. Часть 6. Великолепная десятка
/* displayResults — вывод информации о */
/* счетах в связанном списке */
void displayResults( list< AccountPtr > & accntList )
{
double total = 0.0 ;
cout << "\nИтоговая информация:\n" ;
/* Создание итератора и проход по списку */
list< AccountPtr >::iterator iter ;
iter = accntList.begin( ) ;
while ( iter != accntList.end( ) )
{
AccountPtr pAccount = *iter ;
iter++ ;
pAccount -> display( ) ;
total += pAccount -> acntBalance( ) ;
}
cout << "Итого = " << total << endl ;
}
/* getAccntNo — номер счёта для его создания */
unsigned getAccntNo( )
{
unsigned accntNo ;
cout << "Введите номер счёта: " ;
cin >> accntNo ;
return accntNo ;
}
/* process( Account ) — обработка счёта */
void process( AccountPtr pAccount )
{
cout << "Введите положительное число для вклада,\n"
<< "отрицательное для снятия,"
<< "0 для завершения работы\n" ;
double transaction ;
do
{
cout << ":" ;
cin >> transaction ;
// Вклад
if ( transaction > 0 )
{
pAccount -> deposit( transaction ) ;
}
// Снятие
if ( transaction < 0 )
{
pAccount -> withdrawal( -transaction ) ;
}
} while ( transaction != 0 ) ;
}
Заголовочный файл list содержит определение шаблона класса list из STL. Классы Account , Checking и Savings остаются неизменными ( т.е. такими, как в программе BUDGET3 ). Изменения начинаются с определения типа AccountPtr примерно в середине программы.
_________________
377 стр. Глава 31. Программа BUDGET
Создание списка счетов...378
Функция main( ) создаёт список объектов listAccounts , который имеет тип list< AccountPtr > .
Теоретически я могу реализовать шаблон класса как list< Account* > , но так поступают редко — дабы не портить определения внутри шаблонов классов STL, обычно используют синонимы указателей, полученные при помощи оператора typedef .

«ТипAccountPtr определён с использованием ключевого словаtypedef и представляет собой то же, что иAccount* . Таким образом, везде, где написаноAccountPtr , можно читать "указатель наAccount ".»
[ Помни! ]
Функция main( ) передаёт список указателей на объекты Account функциям getAccounts( ) и displayResults( ) . Метод getAccounts( ) добавляет объекты Account в конец списка при помощи функции-члена push_back( ) .
Функция displayResults( ) может удалять объекты Account из списка при помощи одного из предназначенных для этой цели методов; однако это будет так называемое деструктивное чтение, которое изменяет список ( в нашем случае — удаляя из него объекты ). Поскольку мы хотим иметь возможность работать со списком и после вывода его на экран, нам надо воспользоваться итератором — объектом, который указывает на объекты в списке. Программа в цикле перемещает итератор от одного элемента списка к следующему.
Функция displayResults( ) определяет итератор iter в начале цикла while( ) . Присвоение iter = accntList . begin( ) инициализирует объект iter первым элементом списка. Значение accntList.end( ) представляет собой "объект, непосредственно следующий за последним объектом в контейнере". Таким образом, цикл должен полностью обойти весь список к моменту, когда iter становится равным accntList.end( ) . Выражение *iter даёт нам то, что можно назвать "текущим объектом", а выражение iter++ перемещает итератор к следующему объекту в списке.
Читать дальше