Ñ++ äëÿ íà÷èíàþùèõ

       

Èñïîëüçîâàíèå øàáëîíîâ


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


Ñîäåðæàíèå ðàçäåëà