Выбрать главу

template <class Type>

List<Type>::~List()

{

   ListCell *pt = head;

   while ( pt )

   {

      ListCell *tmp = pt;

      pt = pt->next;

      delete tmp;

   }

   head = tail = 0;

}

template <class Type>

void List<Type>::insert(Type value)

{

   ListCell *pt = new ListCell( value, head );

   assert (pt ! = 0);

   // эта строка добавляется для обработки хвостового узла

   if ( head == 0 )

      tail = pt;

   head = pt;

   theCount++;

}

template <class Type>

void List<Type>::append( Type value )

{

   ListCell *pt = new ListCell( value );

   if ( head == 0 )

      head = pt;

   else

      tail->next = pt;

   tail = pt;

   theCount++;

}

template <class Type>

int List<Type>::is_present( Type value ) const

{

   if ( head == 0 )

      return 0;

   if ( head->val == value || tail->val == value )

      return 1;

   ListCell *pt = head->next;

   for (; pt != tail; pt = pt->next)

      if ( pt->val — value )

         return 1;

   return 0;

}

4. Объявите три списка объектов: типа Strings, типа Cat и типа int.

List<String> string_list;

List<Cat> Cat_List;

List<int> int_List;

5. Жучки: что неправильно в приведенном ниже программном коде? (Предположите, что определяется шаблон класса List, а Cat — это класс, определенный выше в данной книге.)

List<Cat> Cat_List;

Cat Felix;

CatList.append( Felix );

cout << "Felix is " << ( Cat_List.is_present( Felix ) ) ? "" : "not " << "present\n";

ПОДСКАЗКА (поскольку задание не из самых легких): подумайте, чем тип Cat отличается от типа int.

В классе Cat не определен оператор operator==. Все операции, в которых сравниваются значения членов класса iist, таких как is_present, будут вызывать ошибку компиляции. Для уменьшения вероятности возникновения таких ошибок перед объявлением шаблона поместите обширный комментарий, в котором должно быть указано, какие операторы следует определить в классе для успешного выполнения всех его методов.

6. Объявите дружественный оператор operator== для класса List.

friend int operator==( const Type& lhs, const Type& rhs );

7. Напишите выполнение дружественного оператора operator== для класса List.

template <class Type>

int List<Type>::operator==( const Type& lhs, const Type& rhs )

{

   // сначала сравниваем размеры списков

   if ( lhs.theCount != rhs.theCount )

      return 0; // списки различны

   ListCell *lh = lhs.head;

   ListCell *rh = rhs.head;

   for(; lh != 0; lh = lh.next. rh = rh.next )

      if ( lh.value != rh.value )

         return 0;

   return 1; // если они не различны, то совпадают

}

8. Грешитли оператор operator== той же проблемой, которая существует в упражнении 5?

Да. Поскольку сравнение массива включает сравнение элементов, то для элементов также должен быть определен оператор operator!=.

9. Напишите выполнение функции шаблона, осуществляющей операцию обмена данными, в результате чего две переменные должны обменяться содержимым.

// шаблон swap:

// должен иметь оператор присваивания и конструктор-копировщик, определенные для

класса Туре,

template <class Type>

void swap( Type& lhs, Type& rhs)

{

   Type temp( lhs );

   lhs = rhs;

   rhs = temp;

}

10. Напишите выполнение класса SchoolClass, показанного в листинге 19.8, как списка. Для добавления в список четырех студентов используйте функцию push_back(). Затем пройдитесь по полученному списку и увеличьте возраст каждого студента на один год.

#include <list>

template<class T, class A>

void ShowList(const iist<T, А>& aList); // отображаем свойства вектора

typedef list<Student> SchoolClass;

int main()

{

   Student Harry("Harry". 18);

   Student Sally("Sally", 15);

   Student Bill( "Bill", 17);

   Student Peter("Peter", 16);

   SchoolClass GrowingClass;

   GrowingClass.push_back(Harry);

   GrowingClass.push_back(Sally);

   GrowingClass.push_back(Bill);

   GrowingClass.push_back(Peter);

   ShowList(GrowingClass);

   cout << "Один год спустя:\n";

   for (SchoolClass::iterator i = GrowingClass.begin(); i != GrowingClass.end(); ++i)

      i->SetAge(i->GetAge() + 1);

   ShowList(GrowingClass);

   return 0;

}

//

// Отображаем свойства списка

//

template<class T, class A>

void ShowList(const list<T, А>& aList)

{

   for (list<T, A>::const_iterator ci = aList.begin(); ci != aList.end(); ++ci)

      cout << *ci << "\n";

   cout << endl;

}

11. Измените код из упражнение 10 таким образом, чтобы для отображения данных о каждом студенте использовался объект функции.

#include <algorithm>

template<class T>

class Print

{

   public:

      void operator()(const T& t)

      {

         cout << t << "\n";

      }

}

template<class T, class A>