Курс ООП в С презентация. ООП в с++(полный курс). Объекты и классы
Скачать 1.76 Mb.
|
Шаблоны классовВ проекте, состоящем из нескольких файлов, определение шаблона класса обычно выносится в отдельный файл. Но для того, чтобы инстанцировался конкретный экземпляр шаблона класса необходимо, чтобы определение шаблона находилось в одной единице трансляции с этим экземпляром. Поэтому все определение шаблонного класса размещается в заголовочном файле, а затем этот файл подключается к нужным файлам с помощью директивы #include. Чтобы этот файл не включался повторно, используется директива #ifndef. По этой причине реализацию методов шаблона мы размещаем в том же заголовочном файле, где находится и определение класса шаблона – в "group.h". template { first = 0; last = 0; }; Шаблоны классовtemplate { if (last) { last->next = new node last->next->prev = last; last = last->next; last->next = 0; } else { first = new node first->prev = 0; first->next = 0; last = first; } last->data = newdata; }; Шаблоны классовtemplate { node while (nx) { fp(nx->data); nx = nx->next; } } При включении шаблона класса в программу никакие классы не генерируются до тех пор, пока не будет создан экземпляр шаблонного класса, в котором вместо параметра шаблона указывается конкретный тип. Экземпляр создается либо объявлением объекта, либо объявлением указателя на инстанцированный шаблонный тип с присваиванием ему адреса с помощью операции new. Встретив такие объявления, компилятор создает код исходного класса. class dialog { public: dialog(); virtual dialog(); private: group Group; }; Шаблоны классовПриведённая выше диаграмма обозначает, что экземпляр класса dialog содержит атрибут Group типа group , который, в свою очередь, определяется посредством использования шаблона group с формальным параметром T, вместо которого подставляется фактический person или любой другой необходимый тип. Шаблоны классовПример ниже показывает работу с созданным контейнером Group посредством объекта диалога dialog. dialog::dialog() { person x; int q; cout << "How many instances?"; cin >> q; for (int i = 0; i < q; i++) { Group.push_back(x); } Group.for_each(util ::set_value); Group.for_each(util ::show_value); } Создаваемый диалог предоставляет механизмы работы клиента с локально создаваемым сервером – контейнером Group, посредством запроса количества q экземпляров класса person у пользователя и размещением оных в контейнере путём вызова его метода push_back(). Последующее определение состояния каждого объекта группы и вывод сведений о них выполняется с помощью передаваемых методу-итератору for_each() функций, применяемых к последовательности элементов контейнера. Шаблоны классовОтметим, что обеспечить последовательный доступ ко всем частям объекта можно не только определяя итерации как часть протокола объекта, но и создавая отдельные объекты, ответственные за итеративный опрос других структур. Рассмотрим теперь и второй подход по тем причинам, что наличие выделенного итератора позволяет одновременно проводить несколько просмотров одного и того же объекта и, выделение итератора в качестве отдельного механизма поведения способствует большей ясности в описании класса. Пассивный итератор (рассмотренный ранее), применяет функцию, предоставляемую клиентом, ко всем элементам последовательности за одну операцию. Активный итератор (который мы сейчас и рассмотрим), требует каждый раз от клиента явного обращения к себе для перехода к следующему элементу. Шаблоны классовВ таком случае каждому объекту-итератору должен быть поставлен в соответствие определенный элемент объекта-контейнера. Играя роль указателя, активный итератор на самом деле таковым не является, поэтому попытка передачи такого объекта вместо адреса вызовет ошибку. Его работа заключается в том, чтобы переходить к следующему (префиксный оператор ++) или предыдущему элементу в списке (метод end() служит для определения нахождения итератора в его границах). Доступ к самим хранимым элементами данным осуществляется с помощью операторов -> и *. Метод reset() здесь присутствует для "сброса" состояния итератора к началу последовательности. template { public: group_iterator(group void reset(); group_iterator bool end(); T* operator->(); T& operator*(); protected: group node }; |