Èñïîëüçîâàíèå øàáëîíîâ
Íàø êëàññ 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 ¸¢øªðõªõ, þÿ¨ðòôðýþ ûø ªðúþõ ÿþòõôõýøõ? =õ ûº¢°õ ûø ÿ¨õôºÿ¨õôøª¹ þñ þ°øñúõ ¸¨ð÷º, ÿ¨ø þñ¨ðñþªúõ þÿø¸ðýø °ðñûþýð? ¦þ ¸ýøªõ ¸òþõ üýõýøõ.