С++ для начинающих





Скачать 17.65 Mb.
НазваниеС++ для начинающих
страница9/198
Дата публикации21.08.2013
Размер17.65 Mb.
ТипКнига
100-bal.ru > Информатика > Книга
1   ...   5   6   7   8   9   10   11   12   ...   198

2.5. Использование шаблонов


Наш класс IntArray служит хорошей альтернативой встроенному массиву целых чисел. Но в жизни могут потребоваться массивы для самых разных типов данных. Можно предположить, что единственным отличием массива элементов типа double от нашего является тип данных в объявлениях, весь остальной код совпадает буквально.

Для решения данной проблемы в С++ введен механизм шаблонов. В объявлениях классов и функций допускается использование параметризованных типов. Типы-параметры заменяются в процессе компиляции настоящими типами, встроенными или определенными пользователем. Мы можем создать шаблон класса Array, заменив в классе IntArray тип элементов int на обобщенный тип-параметр. Позже мы конкретизируем типы-параметры, подставляя вместо них реальные типы int, double и string. В результате появится способ использовать эти конкретизации так, как будто мы на самом деле определили три разных класса для этих трех типов данных.

Вот как может выглядеть шаблон класса Array:

template

class Array {

public:

explicit Array( int sz = DefaultArraySize );

Array( const elemType *ar, int sz );

Array( const Array &iA );
virtual ~Array() { delete[] _ia; }
Array& operator=( const Array & );

int size() const { return _size; }
virtual elemType& operator[]( int ix )

{ return _ia[ix]; }
virtual void sort( int,int );

virtual int find( const elemType& );

virtual elemType min();

virtual elemType max();

protected:

void init( const elemType*, int );

void swap( int, int );

static const int DefaultArraySize = 12;

int _size;

elemType *_ia;

};

Ключевое слово template говорит о том, что задается шаблон, параметры которого заключаются в угловые скобки (<>). В нашем случае имеется лишь один параметр elemType; ключевое слово class перед его именем сообщает, что этот параметр представляет собой тип.

При конкретизации класса-шаблона Array параметр elemType заменяется на реальный тип при каждом использовании, как показано в примере:

#include

#include "Array.h"
int main()

{

const int array_size = 4;
// elemType заменяется на int

Array ia(array_size);
// elemType заменяется на double

Array da(array_size);
// elemType заменяется на char

Array ca(array_size);
int ix;
for ( ix = 0; ix < array_size; ++ix ) {

ia[ix] = ix;

da[ix] = ix * 1.75;

ca[ix] = ix + 'a';

}
for ( ix = 0; ix < array_size; ++ix )

cout << "[ " << ix << " ] ia: " << ia[ix]

<< "\tca: " << ca[ix]

<< "\tda: " << da[ix] << endl;
return 0;

}

Здесь определены три экземпляра класса Array:

Array ia(array_size);


Array da(array_size);


Array ca(array_size);

Что делает компилятор, встретив такое объявление? Подставляет текст шаблона Array, заменяя параметр elemType на тот тип, который указан в каждом конкретном случае. Следовательно, объявления членов приобретают в первом случае такой вид:

// Array ia(array_size);

int _size;

int *_ia;

Заметим, что это в точности соответствует определению массива IntArray.

Для оставшихся двух случаев мы получим следующий код:

// Array da(array_size);


int _size;

double *_ia;
// Array ca(array_size);

int _size;


char *_ia;

Что происходит с функциями-членами? В них тоже тип-параметр elemType заменяется на реальный тип, однако компилятор не конкретизирует те функции, которые не вызываются в каком-либо месте программы. (Подробнее об этом в разделе 16.8.)

При выполнении программа этого примера выдаст следующий результат:

[ 0 ] ia: 0 ca: a da: 0

[ 1 ] ia: 1 ca: b da: 1.75

[ 2 ] ia: 2 ca: c da: 3.5

[ 3 ] ia: 3 ca: d da: 5.25

Механизм шаблонов можно использовать и в наследуемых классах. Вот как выглядит определение шаблона класса ArrayRC:

#include


#include "Array.h"
template

class ArrayRC : public Array {

public:

ArrayRC( int sz = DefaultArraySize )

: Array( sz ) {}

ArrayRC( const ArrayRC& r )

: Array( r ) {}

ArrayRC( const elemType *ar, int sz )

: Array( ar, sz ) {}
elemType& ArrayRC::operator[]( int ix )

{

assert( ix >= 0 && ix < Array::_size );

return _ia[ ix ];

}

private:

// ...


};

Подстановка реальных параметров вместо типа-параметра elemType происходит как в базовом, так и в производном классах. Определение

ArrayRC ia_rc(10);

ведет себя точно так же, как определение IntArrayRC из предыдущего раздела. Изменим пример использования из предыдущего раздела. Прежде всего, чтобы оператор

// функцию swap() тоже следует сделать шаблоном


swap( ia1, 1, ia1.size() );

был допустимым, нам потребуется представить функцию swap() в виде шаблона.

#include "Array.h"



template

inline void

swap( Array &array, int i, int j )

{

elemType tmp = array[ i ];

array[ i ] = array[ j ];

array[ j ] = tmp;


}

При каждом вызове swap() генерируется подходящая конкретизация, которая зависит от типа массива. Вот как выглядит программа, использующая шаблоны Array и ArrayRC:

#include


#include "Array.h"

#include "ArrayRC.h"
template

inline void

swap( Array &array, int i, int j )

{

elemType tmp = array[ i ];

array[ i ] = array[ j ];

array[ j ] = tmp;

}
int main()

{

Array ia1;

ArrayRC ia2;
cout << "swap() with Array ia1" << endl;

int size = ia1.size();

swap( ia1, 1, size );
cout << "swap() with ArrayRC ia2" << endl;

size = ia2.size();

swap( ia2, 1, size );
return 0;


}

Упражнение 2.13

Пусть мы имеем следующие объявления типов:

template class Array;


enum Status { ... };


typedef string *Pstring;

Есть ли ошибки в приведенных ниже описаниях объектов?


(a) Array< int*& > pri(1024);

(b) Array< Array > aai(1024);

(c) Array< complex< double > > acd(1024);

(d) Array< Status > as(1024);

(e) Array< Pstring > aps(1024);

Упражнение 2.14

Перепишите следующее определение, сделав из него шаблон класса:

class example1 {

public:

example1 (double min, double max);

example1 (const double *array, int size);
double& operator[] (int index);

bool operator== (const example1&) const;
bool insert (const double*, int);

bool insert (double);
double min (double) const { return _min; };

double max (double) const { return _max; };
void min (double);

void max (double);
int count (double value) const;
private:

int size;

double *parray;

double _min;

double _max;

}

Упражнение 2.15

Имеется следующий шаблон класса:

template class Example2 {


public:

explicit Example2 (elemType val=0) : _val(val) {};
bool min(elemType value) { return _val < value; }

void value(elemType new_val) { _val = new_val; }

void print (ostream &os) { os << _val; }
private:

elemType _val;

}
template

ostream& operator<<(ostream &os,const Example2 &ex)


{ ex.print(os); return os; }

Какие действия вызывают следующие инструкции?


(a) Example2*> ex1;

(b) ex1.min (&ex1);

(c) Example2 sa(1024),sb;

(d) sa = sb;

(e) Example2 exs("Walden");

(f) cout << "exs: " << exs << endl;

Упражнение 2.16

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

explicit Example2 (elemType val=0) : _val(val) {};

Однако не все типы могут быть инициализированы нулем (например, тип string), поэтому определение объекта

Example2 exs("Walden");

является правильным, а

Example2 exs2;

приведет к синтаксической ошибке4. Также ошибочным будет вызов функции min(), если для данного типа не определена операция меньше. С++ не позволяет задать ограничения для типов, подставляемых в шаблоны. Как вы думаете, было бы полезным иметь такую возможность? Если да, попробуйте придумать синтаксис задания ограничений и перепишите в нем определение класса Example2. Если нет, поясните почему.

Упражнение 2.17

Как было показано в предыдущем упражнении, попытка использовать шаблон Example2 с типом, для которого не определена операция меньше, приведет к синтаксической ошибке. Однако ошибка проявится только тогда, когда в тексте компилируемой программы действительно встретится вызов функции min(), в противном случае компиляция пройдет успешно. Как вы считаете, оправдано ли такое поведение? Не лучше ли предупредить об ошибке сразу, при обработке описания шаблона? Поясните свое мнение.
1   ...   5   6   7   8   9   10   11   12   ...   198

Похожие:

С++ для начинающих iconКалендарно-Тематическое планирование элективного курса «Компьютер для начинающих» для 5 класс
Программа элективного курса «Компьютер для начинающих» для 5 класса (Рекомендована Экспертным Советом му «Управление образования...
С++ для начинающих iconПособие на каждый день для начинающих студентов Губкинского университета...
У нас так принято. Пособие на каждый день для начинающих студентов Губкинского университета и не только для них. Авторы: доцент Л....
С++ для начинающих iconСписок используемой литературы на тему «Компьютерная графика и Анимация»...
Издательство: Педагогика–пресс «Информатика: Энциклопедический словарь для начинающих.» – 1994 – С. 121-154
С++ для начинающих iconПояснительная записка Программа рассчитана на 30 час ( 2 часа в неделю)....
Учебник английского языка «Страна чудес Wonderland Pre-Junior для начинающих» Кристина Бруни Эдинбург, «Пирсон», 2012
С++ для начинающих iconМетодические рекомендации для учителей, начинающих работать по курсу...

С++ для начинающих iconНик Бостром. Рассуждение о Конце Света для начинающих. Алексей Турчин
Оценочные средства для текущего контроля успеваемости, промежуточной итоговой аттестации студентов д/о и з/о
С++ для начинающих iconПрограмма по формированию навыков безопасного поведения на дорогах...
Уровень подготовленности: для начинающих; для среднего и любого уровня подготовленности; для подготовленных
С++ для начинающих iconRu Персональный компьютер, или "Азбука pc" для начинающих http
Олимпиады и контрольно-измерительные материалы по информатике и ит олимпиадная информатика
С++ для начинающих iconНемецкий язык для начинающих
С 34 Лингвострановедение и страноведение: учебно-методический комплекс / А. А. Сибгатуллина – Елабуга: Изд-во егпу, 2010. – 24с
С++ для начинающих iconПрограмма по формированию навыков безопасного поведения на дорогах...
Курс для начинающих 1 (А1): для абсолютных новичков. Разговор для первой ориентации,ситуации повседневной жизни,грамматических структур...
С++ для начинающих iconПрограмма по формированию навыков безопасного поведения на дорогах...
...
С++ для начинающих iconПрограмма по формированию навыков безопасного поведения на дорогах...
...
С++ для начинающих iconПрограмма по формированию навыков безопасного поведения на дорогах...
...
С++ для начинающих iconПособие на каждый день для начинающих студентов Нефтегаза и не только для них Тюмень
Использовано пособие «У нас так принято!» Российского государственного университета нефти и газа им. Губкина
С++ для начинающих iconПоложение о XV городской конференции учащихся «Первая ступень в науку»
Создание условий для формирования познавательного интереса у начинающих исследователей в различных отраслях науки
С++ для начинающих iconПрограмма по формированию навыков безопасного поведения на дорогах...
Аэробика с использованием степ платформы. Рекомендуется для начинающих. Продолжительность 45 минут


Школьные материалы


При копировании материала укажите ссылку © 2013
контакты
100-bal.ru
Поиск