Глава 18. Классы-контейнеры 433

cout « "Введите идентификатор (id) и рейтинг студента ^> (для выхода наберите stop):" « endl;

do (

cin » id;

if (id != "stop") { float grade;

cin » grade;

studentList.Addfnew STUDENT(id, grade));

} } while (id \= "stop");

cout « endl « "Введен следующий список студентов:" « endl « setiosflags(ios::fixed) « setprecision(l);

for (int i = 0; i < studentList.GetItemsInContainerO; i++), cout « " [" « i « "] "

« student.List[i]->GetId() « " « studentList[i]->GetGrade() « endl;

return 0; . )

Имя класса-шаблона указывает на тип хранения. Если контейнер содержит указатели на объекты, то за начальным т следует i:

typedef TIArrayAsVector<STUDENT> STUDENT_LIST;

Для того чтобы можно было использовать прямой контейнер, хранимые объекты должны иметь правильно определенные конструктор по умолчанию, конструктор копий, операцию присваивания и операцию ==. Иногда бывает трудно или невозможно определить операцию ==. Предположим, например, что операция == для класса, экземпляры которого должны храниться в контейнере, не определена и код определения класса недоступен. Единственный способ использования прямого контейнера в этой ситуации -— это определить производный класс и уже в нем определить операцию ==. Только тогда объекты нового типа можно хранить в прямом контейнере. В косвенных контейнерах хранятся указатели, для которых также должны быть правильно определены все необходимые функции.

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

Принадлежность контейнеров

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