Мониторинг обменных курсов валют
18c0693f

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


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

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

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

template <class elemType>

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 <iostream>

#include "Array.h"

int main()

{

а const int array_size = 4;

а // elemType чрьхэ хЄё  эр int

а Array<int> ia(array_size);

а // elemType чрьхэ хЄё  эр double

а Array<double> da(array_size);

а // elemType чрьхэ хЄё  эр char

а Array<char> 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;

}

¦фхё№ юяЁхфхыхэv ЄЁш ¤ъчхьяы Ёр ъырёёр Array:

Array<int> ia(array_size);

Array<double> da(array_size);

Array<char> ca(array_size);

+Єю фхырхЄ ъюьяшы ЄюЁ, тёЄЁхЄшт Єръюх юс· тыхэшх? ¦юфёЄрты хЄ ЄхъёЄ °рсыюэр Array, чрьхэ   ярЁрьхЄЁ elemType эр ЄюЄ Єшя, ъюЄюЁvщ єърчрэ т ърцфюь ъюэъЁхЄэюь ёыєўрх. TыхфютрЄхы№эю, юс· тыхэш  ўыхэют яЁшюсЁхЄр¦Є т яхЁтюь ёыєўрх Єръющ тшф:

// Array<int> ia(array_size);

int _size;

int *_ia;

¦рьхЄшь, ўЄю ¤Єю т ЄюўэюёЄш ёююЄтхЄёЄтєхЄ юяЁхфхыхэш¦ ьрёёштр IntArray.

-ы  юёЄрт°шїё  фтєї ёыєўрхт ьv яюыєўшь ёыхфє¦•шщ ъюф:

// Array<double> da(array_size);

intаааа _size;

double *_ia;

// Array<char> ca(array_size);

intаа _size;

char *_ia;

+Єю яЁюшёїюфшЄ ё ЇєэъЎш ьш-ўыхэрьш? T эшї Єюцх Єшя-ярЁрьхЄЁ elemType чрьхэ хЄё  эр Ёхры№эvщ Єшя, юфэръю ъюьяшы ЄюЁ эх ъюэъЁхЄшчшЁєхЄ Єх ЇєэъЎшш, ъюЄюЁvх эх тvчvтр¦Єё  т ъръюь-ышсю ьхёЄх яЁюуЁрььv. (¦юфЁюсэхх юс ¤Єюь т Ёрчфхых 16.8.)

¦Ёш тvяюыэхэшш яЁюуЁрььр ¤Єюую яЁшьхЁр тvфрёЄ ёыхфє¦•шщ Ёхчєы№ЄрЄ:

[ 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

¦хїрэшчь °рсыюэют ьюцэю шёяюы№чютрЄ№ ш т эрёыхфєхьvї ъырёёрї. TюЄ ъръ тvуы фшЄ юяЁхфхыхэшх °рсыюэр ъырёёр ArrayRC:



#include <cassert>

#include "Array.h"

template <class elemType>

class ArrayRC : public Array<elemType> {

public:

ааа ArrayRC( int sz = DefaultArraySize )

ааааааааааа : Array<elemType>( sz ) {}

ааа ArrayRC( const ArrayRC& r )

ааааааааааа : Array<elemType>( r ) {}

ааа ArrayRC( const elemType *ar, int sz )

ааааааааааа : Array<elemType>( ar, sz ) {}

ааа elemType& ArrayRC<elemType>::operator[]( int ix )

ааа {

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

ааааааа return _ia[ ix ];

ааа }

private:

// ...

};

¦юфёЄрэютър Ёхры№эvї ярЁрьхЄЁют тьхёЄю Єшяр-ярЁрьхЄЁр elemType яЁюшёїюфшЄ ъръ т срчютюь, Єръ ш т яЁюшчтюфэюь ъырёёрї. +яЁхфхыхэшх

ArrayRC<int> ia_rc(10);

тхфхЄ ёхс  Єюўэю Єръ цх, ъръ юяЁхфхыхэшх IntArrayRC шч яЁхфvфє•хую Ёрчфхыр. Lчьхэшь яЁшьхЁ шёяюы№чютрэш  шч яЁхфvфє•хую Ёрчфхыр. ¦Ёхцфх тёхую, ўЄюсv юяхЁрЄюЁ

// ЇєэъЎш¦ swap() Єюцх ёыхфєхЄ ёфхырЄ№ °рсыюэюь

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

сvы фюяєёЄшьvь, эрь яюЄЁхсєхЄё  яЁхфёЄртшЄ№ ЇєэъЎш¦ swap() т тшфх °рсыюэр.

#include "Array.h"

template <class elemType>

inline void

swap( Array<elemType> &array, int i, int j )

{

а elemType tmp = array[ i ];

а array[ i ] = array[ j ];

а array[ j ] = tmp;

}

¦Ёш ърцфюь тvчютх swap() ухэхЁшЁєхЄё  яюфїюф •р  ъюэъЁхЄшчрЎш , ъюЄюЁр  чртшёшЄ юЄ Єшяр ьрёёштр. TюЄ ъръ тvуы фшЄ яЁюуЁрььр, шёяюы№чє¦•р  °рсыюэv Array ш ArrayRC:

#include <iostream>

#include "Array.h"

#include "ArrayRC.h"

template <class elemType>

inline void

swap( Array<elemType> &array, int i, int j )

{

а elemType tmp = array[ i ];

а array[ i ] = array[ j ];

а array[ j ] = tmp;

}

int main()

{

а Array<int>аа ia1;

а ArrayRC<int> ia2;

а cout << "swap() with Array<int> ia1" << endl;

а int size = ia1.size();

а swap( ia1, 1, size );



а cout << "swap() with ArrayRC<int> ia2" << endl;

а size = ia2.size();

а swap( ia2, 1, size );

а return 0;

}

LяЁрцэхэшх 2.13

¦єёЄ№ ьv шьххь ёыхфє¦•шх юс· тыхэш  Єшяют:

template<class elemType> class Array;

enum Status { ... };

typedef string *Pstring;

+ёЄ№ ыш ю°шсъш т яЁштхфхээvї эшцх юяшёрэш ї юс·хъЄют?

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

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

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

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

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

LяЁрцэхэшх 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;

}

LяЁрцэхэшх 2.15

LьххЄё  ёыхфє¦•шщ °рсыюэ ъырёёр:

template <class elemType> 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 <class elemType>

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

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

¦ръшх фхщёЄтш  тvчvтр¦Є ёыхфє¦•шх шэёЄЁєъЎшш?

(a) Example2<Array<int>*> ex1;

(b) ex1.min (&ex1);

(c) Example2<int> sa(1024),sb;

(d) sa = sb;

(e) Example2<string> exs("Walden");

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



LяЁрцэхэшх 2.16

¦ЁшьхЁ шч яЁхфvфє•хую єяЁрцэхэш  эръырфvтрхЄ юяЁхфхыхээvх юуЁрэшўхэш  эр Єшяv фрээvї, ъюЄюЁvх ьюуєЄ сvЄ№ яюфёЄртыхэv тьхёЄю elemType. Tръ,а ярЁрьхЄЁ ъюэёЄЁєъЄюЁр шьххЄ яю єьюыўрэш¦ чэрўхэшх 0:

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

+фэръю эх тёх Єшяv ьюуєЄ сvЄ№ шэшЎшрышчшЁютрэv эєыхь (эряЁшьхЁ, Єшя string), яю¤Єюьє юяЁхфхыхэшх юс·хъЄр

Example2<string> exs("Walden");

 ты хЄё  яЁртшы№эvь, р

Example2<string> exs2;

яЁштхфхЄ ъ ёшэЄръёшўхёъющ ю°шсъх[4]. Tръцх ю°шсюўэvь сєфхЄ тvчют ЇєэъЎшш min(), хёыш фы  фрээюую Єшяр эх юяЁхфхыхэр юяхЁрЎш  ьхэ№°х. T++ эх яючтюы хЄ чрфрЄ№ юуЁрэшўхэш  фы  Єшяют, яюфёЄрты хьvї т °рсыюэv. ¦ръ тv фєьрхЄх, сvыю сv яюыхчэvь шьхЄ№ Єръє¦ тючьюцэюёЄ№? +ёыш фр, яюяЁюсєщЄх яЁшфєьрЄ№ ёшэЄръёшё чрфрэш  юуЁрэшўхэшщ ш яхЁхяш°шЄх т эхь юяЁхфхыхэшх ъырёёр Example2. +ёыш эхЄ, яю ёэшЄх яюўхьє.

LяЁрцэхэшх 2.17

¦ръ сvыю яюърчрэю т яЁхфvфє•хь єяЁрцэхэшш, яюяvЄър шёяюы№чютрЄ№ °рсыюэ Example2 ё Єшяюь, фы  ъюЄюЁюую эх юяЁхфхыхэр юяхЁрЎш  ьхэ№°х, яЁштхфхЄ ъ ёшэЄръёшўхёъющ ю°шсъх. +фэръю ю°шсър яЁю тшЄё  Єюы№ъю Єюуфр, ъюуфр т ЄхъёЄх ъюьяшышЁєхьющ яЁюуЁрььv фхщёЄтшЄхы№эю тёЄЁхЄшЄё  тvчют ЇєэъЎшш min(), т яЁюЄштэюь ёыєўрх ъюьяшы Ўш  яЁющфхЄ єёях°эю. ¦ръ тv ёўшЄрхЄх, юяЁртфрэю ыш Єръюх яютхфхэшх? =х ыєў°х ыш яЁхфєяЁхфшЄ№ юс ю°шсъх ёЁрчє, яЁш юсЁрсюЄъх юяшёрэш  °рсыюэр? ¦ю ёэшЄх ётюх ьэхэшх.





Самый выгодный курс обмена валюты