Адаптеры указателей на функции
Äëя òîãî ÷òîáû ïðèìåíяòü ñâяçûâaòåëè ê îáû÷íûì óêaçaòåëяì ía ôóíêöèè, òðå- áóþòñя ñïåöèaëüíûå ïðåîáðaçîâaòåëè, èëè aäaïòåðû. Còaíäaðòíaя áèáëèîòåêa îïðåäåëяåò äâa ôóíêöèîíaëüíûõ îáúåêòa — óêaçaòåëü ía óíaðíóþ ôóíêöèþ pOinter_tO_unary_funCtiOn è óêaçaòåëü ía áèíaðíóþ ôóíêöèþ pOinter_tO_binary_ funCtiOn, a òaêæå äâå ôóíêöèè-aäaïòåða ptr_fun ñ îäíèì è äâóìя aðãóìåíòaìè, êî- òîðûå ïðåîáðaçóþò ïåðåäaííûé èì â êa÷åñòâå ïaðaìåòða óêaçaòåëü ía ôóíêöèþ â ôóíêöèîíaëüíûé îáúåêò.
Íèæå ïðèâåäåíî îïèñaíèå øaáëîía êëañña è ôóíêöèè äëя óíaðíûõ è áèíaðíûõ ôóíêöèé:
template
Class pOinter_tO_unary_funCtiOn : publiC unary_funCtiOn{
publiC:
expliCit pOinter_tO_unary_funCtiOn(Result (*f)(Arg)); Result OperatOr()(Arg x) COnst; // Âîçâðaùaåò f(x)
};
template pOinter_tO_unary_funCtiOn
ptr_fun(Result (*f)(Arg));
template
Class pOinter_tO_binary_funCtiOn : publiC binary_funCtiOn{ publiC:
expliCit pOinter_tO_binary_funCtiOn(Result (*f)(Arg1, Arg2)); Result OperatOr()(Arg1 x, Arg2 y) COnst;
};
template pOinter_tO_binary_funCtiOn
ptr_fun(Result (*f)(Arg1, Arg2));
Ïðèìåð ïðèìåíåíèя aäaïòåða ôóíêöèè:
inClude inClude inClude using namespaCe std; struCt A{
int x, y;
};
bOOl lss(A a1, A a2){return a1.x < a2.x;} int main(){
A ma[5] = {{2, 4}, {3, 1}, {2, 2}, {1, 2}, {1, 2}};
A elem = {3, 0};
COut << COunt_if(ma, ma + 5, bind2nd(ptr_fun(lss), elem)); return 0;
}
Ôóíêöèя lss çaäaåò ïðaâèëî ñðaâíåíèя ýëåìåíòîâ ñòðóêòóðû À. Àëãîðèòì ñòaí- äaðòíîé áèáëèîòåêè COunt_if âû÷èñëяåò êîëè÷åñòâî ýëåìåíòîâ ñòðóêòóðû ma, óäîâëåòâîðяþùèõ óñëîâèþ, çaäaííîìó òðåòüèì ïaðaìåòðîì. Ýòèì ïaðaìåòðîì яâëяåòñя ôóíêöèîíaëüíûé îáúåêò, ñîçäaííûé ñâяçûâaòåëåì bind2nd èç ôóíêöèî- íaëüíîãî îáúåêòa, ïîëó÷åííîãî èç ôóíêöèè lss ñ ïîìîùüþ aäaïòåða ptr_fun,è ïå- ðåìåííîé, ïîäñòaâëяåìîé ía ìåñòî âòîðîãî ïaðaìåòða ôóíêöèè.  ðåçóëüòaòå áó- äåò âû÷èñëåíî êîëè÷åñòâî ýëåìåíòîâ ñòðóêòóðû À, ïîëå õ êîòîðûõ ìåíüøå 3 (ðåçóëüòaò — 4).
 êa÷åñòâå âòîðîãî ïðèìåða ðaññìîòðèì âåêòîð èç îáúåêòîâ êëañña mOnstr, ââå- äåííîãî ðaíåå (ñì. ñ. 183). Ïðèâåäåííaя íèæå ïðîãðaììa ñ ïîìîùüþ aëãîðèòìa ñòaíäaðòíîé áèáëèîòåêè COunt_if (ñì. ñ. 345) âû÷èñëяåò â âåêòîðå êîëè÷åñòâî ìîíñòðîâ, çäîðîâüå êîòîðûõ ïîøaòíóëîñü (äîïóñòèì, ÷òî ýòîò ïå÷aëüíûé ôaêò èìååò ìåñòî ïðè çía÷åíèè ïîëя health < 30). Äëя êðaòêîñòè ïðèâåäåíû òîëüêî íå- îáõîäèìûå ìåòîäû êëañña:
inClude inClude inClude inClude using namespaCe std;
enum COlOr {red, green, blue}; Class mOnstr{
int health, ammO;
COlOr skin;
Char *name;
publiC:
mOnstr(int he = 100, int am = 10); mOnstr(COlOr sk);
mOnstr(Char * nam); mOnstr(COnst mOnstr &M);
~mOnstr() {delete [] name;} OperatOr int(){return health;} int get_health(){;return health;} friend Ostream&
OperatOr <<(Ostream & Out, mOnstr & m){
return Out << "mOnstr: " << " ammO = "<< m.ammO
<< " health=" << m.health <};
mOnstr::mOnstr(int he, int am):
health (he), ammO (am), skin (red), name (0){}
mOnstr::mOnstr(COnst mOnstr &M){
if (M.name){ name = new Char [strlen(M.name) + 1]; strCpy(name, M.name);}
else name = 0;
health = M.health; ammO = M.ammO; skin = M.skin;
}
mOnstr::mOnstr(COlOr sk){ switCh (sk){
Case red :
health = 1; ammO = 10; skin = red; name = 0; break; Case green:
health = 2; ammO = 20; skin = green; name = 0; break; Case blue:
health = 3; ammO = 40; skin = blue; name = 0; break;
}}
mOnstr::mOnstr(Char * nam){
name = new Char [strlen(nam) + 1]; strCpy(name, nam); health = 200; ammO = 10; skin = red;
}
bOOl less_health (mOnstr m1, mOnstr m2){ return m1.get_health() < m2.get_health() ;}
int main(){
veCtOr m; mOnstr M (10, 30); m.push_baCk(M);
m.push_baCk(mOnstr("vasia")); m.push_baCk(mOnstr(red)); COut << " MONSTRY:" << endl;
fOr (inti= 0; iCOut << " COUNT_IF: ";
COut << COunt_if(m.begin(), m.end(), bind2nd(ptr_fun(less_health), 20));
return 0;
}
Áóëåâa ôóíêöèя less_health ñðaâíèâaåò ïîëя health ó äâóõ ïåðåäaííûõ åé aðãó- ìåíòîâ êëañña mOnstr. ×òîáû ñðaâíèòü ïîëå health ñ êîíñòaíòîé, òðåáóåòñя ñâя- çaòü ñ íåé âòîðîé aðãóìåíò ýòîé ôóíêöèè. Câяçûâaòåëü bind2nd äîëæåí ïîëó÷aòü â êa÷åñòâå ïåðâîãî aðãóìåíòa ôóíêöèîíaëüíûé îáúåêò, êîòîðûé ôîðìèðóåòñя ñ ïîìîùüþ aäaïòåða ptr_fun. Ðåçóëüòaò ðaáîòû ïðîãðaììû (áîëüíûõ ìîíñòðîâ — 2 øòóêè):
MONSTRY:
mOnstr: ammO = 30 health = 10 mOnstr: ammO = 10 health = 200 mOnstr: ammO = 10 health = 1
COUNT_IF: 2
Do'stlaringiz bilan baham: |