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