Освой самостоятельно С++ за 21 день.
Шрифт:
6. Что представляют собой итераторы?
Это обобщенные указатели. Итератор можно инкрементировать, чтобы он указывал на следующий узел в последовательности. К нему также можно применить операцию разыменования, чтобы возвратить узел, на который он указывает.
7. Что такое объект функции?
Это экземпляр класса, в котором определен перегруженный оператор вызова функции . Объект функции можно также использовать как обычную функцию.
Упражнения
1.
class List
{
public:
List:head(0),tail(0), tbeCount(0) { }
virtual ~List;
void insert( int value );
void append( int value );
int is_present( int value ) const;
int is_empty const { return head == 0: }
int count const { return theCount; }
private:
class ListCell
{
public:
ListCell(int value, ListCell *cell = ):val(value),next(cell){ }
int val;
ListCell *next;
};
ListCell *head;
ListCell *tail;
int theCount;
};
Вот один из способов выполнения этого шаблона:
template <class Type>
class List
{
public:
List:head(0),tail(0),theCount(0) { }
virtual ~List;
void insert( Type value );
void append( Type value );
int is_present( Type value ) const;
int is_empty const { return head == 0; }
int count const { return theCount; }
private:
class ListCell
{
public:
ListCell(Type value, ListCell *cell = O):val(value),next(cell) { }
Type val;
ListCell *next;
};
ListCell *head;
ListCell *tail;
int theCount;
};
2. Напишите выполнение обычной (не шаблонной) версии класса List.
void List::insert(int value)
{
ListCell *pt = new ListCell( value, head );
assert (pt ! = 0);
// эта строка добавляется для обработки хвостового узла
if ( head -= 0 ) tail = pt,
head = pt;
theCount++;
}
void List::append( int value )
{
ListCell *pt = new ListCell( value );
if ( head — 0 )
head = pt;
else
tail->next = pt:
tail = pt;
theCount++;
}
int List::is_present( int 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;
}
3. Напишите шаблонный вариант выполнения.
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, будут вызывать ошибку компиляции. Для уменьшения вероятности возникновения таких ошибок перед объявлением шаблона поместите обширный комментарий, в котором должно быть указано, какие операторы следует определить в классе для успешного выполнения всех его методов.