You are on page 1of 76

LP TRNH C/C++ NNG CAO Yu cu trc khi c: hc xong Lp trnh C/C++ cn bn BI 1: NHC LI V C/C++ Nhp xut c bn CODE #definemax(a,b)(a>b)?

a:b//khaibomacro typedefunsignedintbyte;//nhnghakiud liu constfloatPI=3.14;//khaibohngs charc;chars[20]; Cch ca C CODE //khngdngscannumunnhpkhongtrng gets(s);//cth nhpkhongtrng puts(s); fflush(stdin);//xab mnhp c=getchar(); putchar; Cch ca C++ CODE //khngdngcin>>numunnhpkhongtrng cin.getline(a,21);//cth nhpkhongtrng cout<<a; cin.get();//xab mnhp Con tr c bn CODE inta=5,*p; //p=3;//khonghopvevikhongthegangiatrikieuintchobienkieuint* //&p=3;//khonghoplevidiachicuaplacodinh p=&a;//hople,gandiachimaptroden *p=3;//hople,gangiatritaidiachimaptroden cout<<p<<endl;//caigidobatki,diachicuaa cout<<&p<<endl;//caigidobatki,diachicuap cout<<*p<<endl;//3,dau*lucnaymangynghia"giatritaidiachicua" Truyn gi tr cho hm Trong C c khi nim con tr (pointer) Trong C++ c thm khi nim tham chiu (reference) CODE inta; int&b=a; Lc ny bin a c mt ci nickname l b Nh vy c tt c 3 cch vit hm v truyn tham s Cch 1: CODE voidadd10(inta) { a=a+10; }

gi: add10(n); Khng hiu qu, a vn gi nguyn gi tr Cch 2: CODE voidadd10(int*a) { *a=*a+10; } gi: add10(&n); Hiu qu. Cch 3: CODE voidadd10(int&a) { a=a+10; } gi: add10(n); Hiu qu, tin hn cch 2. Nhp xut d liu vi kiu mng s nguyn CODE inta[3]; Truyn d liu trc tip theo kiu C, cch 1 CODE for(inti=0;i<3;++i)scanf("%d",&(*(a+i))); for(inti=0;i<3;++i)printf("%d",*(a+i)); Truyn d liu trc tip theo kiu C, cch 2 CODE for(inti=0;i<3;++i)scanf("%d",&a[i]); for(inti=0;i<3;++i)printf("%d",a[i]); Truyn d liu trc tip theo kiu C++, cch 1 CODE for(inti=0;i<3;++i)cin>>*(a+i); for(inti=0;i<3;++i)cout<<*(a+i); Truyn d liu trc tip theo kiu C++, cch 2 CODE for(inti=0;i<3;++i)cin>>a[i]; for(inti=0;i<3;++i)cout<<a[i]; Nhp xut d liu bng hm vi kiu mng s nguyn Nhp xut d liu bng hm vi kiu mng s nguyn theo kiu C, cch 1

CODE voidinput(int[]); input(a); voidinput(int*a) { for(inti=0;i<3;++i) scanf("%d",&(*(a+i))); } voidoutput(int[]); output(a); voidoutput(int*a) { for(inti=0;i<3;++i) printf("%d",*(a+i)); } Nhp xut d liu bng hm vi kiu mng s nguyn theo kiu C, cch 2 CODE voidinput(int[]); input(a); voidinput(inta[]) { for(inti=0;i<3;++i) scanf("%d",&a[i]); } voidoutput(int[]); output(a); voidoutput(inta[]) { for(inti=0;i<3;++i) printf("%d",a[i]); } Nhp xut d liu bng hm vi kiu mng s nguyn theo kiu C++, cch 1 CODE voidinput(int[]); input(a); voidinput(int*a) { for(inti=0;i<3;++i) cin>>*(a+i); } voidoutput(int[]); output(a); voidoutput(int*a) { for(inti=0;i<3;++i) cout<<*(a+i); } Nhp xut d liu bng hm vi kiu mng s nguyn theo kiu C++, cch 2 CODE voidinput(int[]);

input(a); voidinput(inta[]) { for(inti=0;i<3;++i) cin>>a[i]; } voidoutput(int[]); output(a); voidoutput(inta[]) { for(inti=0;i<3;++i) cout<<a[i]; } Nhp xut d liu vi kiu mng s thc Cch dng bin tm CODE floata[2][3],temp; for(inti=0;i<2;++i) for(intj=0;i<3;++j) { scanf("%f\n",&temp); a[i][j]=temp; } Cch dng con tr CODE floata[2][3];float*p; p=(float*)a; for(inti=0;i<2*3;++i) scanf("%f",(p+i)); Nhp mng s thc 2 chiu bng cch dng p kiu CODE floata[3][2];float*p;p=(float*)a; for(inti=0;i<3;i++) for(intj=0;j<2;j++) scanf("%f",((float*)p+i*2+j)); Xut mng s thc 2 chiu bng cch dng p kiu CODE floata[3][2];float*p;p=(float*)a; for(inti=0;i<3;i++) for(intj=0;j<2;j++) printf("%f\n",*(p+i*2+j)); Nhp mng s thc 2 chiu bng cch dng malloc CODE float**p;p=(float**)malloc(2); for(inti=0;i<3;i++) for(intj=0;j<2;j++) scanf("%f",(p+i*2+j));

Xut mng s thc 2 chiu bng cch dng malloc CODE float**p;p=(float**)malloc(2); for(inti=0;i<3;i++) for(intj=0;j<2;j++) printf("%f\n",*(p+i*2+j)); Bi ny ch c gi tr tham kho, tng hp kin thc.

BI 2: NHC LI V C/C++ (TIP THEO) Cu trc (struct) Con tr cu trc (struct pointer) CODE structStudent { intid; }; Student*s; Studentm; s=&m; s->id=3;//means(*s).id cout<<m.id; Sao chp cu trc CODE structStudent { intid; char*name;//mtcontr,khngphimtmng }; Studenta; chartemp[20]; cin>>temp; a.name=newchar[strlen(temp)+1]; strcpy(a.name,temp);//phidngbintm Studentb=a; strcpy(b.name,a.name);//phidngstrcpy,nukhngs saochpach b nh Gi hm vi cu trc CODE structStudent{ charname[10]; intid; }; Studentm[3],a; m[0]=(Student){"Pete",1}; add(m[0].name,&m[0].id); C 4 cch thm d liu vo cu trc. Cch 1 CODE voidadd(charname[],int*place) { cin>>name; cin.get(); cin>>*place; } add(a.name,&a.id); Cch 2 CODE

voidadd(Student&s) { cin>>s.name; cin.get(); cin>>s.id; } add10(a); Cch 3 CODE voidadd(Student*s) { cin>>(*s).name; cin.get(); cin>>(*s).id; } add(&a); Cch 4 CODE voidadd(Student*s) { cin>>s->name; cin.get(); cin>>s->id; } add(&a); Ton t sizeof vi struct CODE structHello { charc; doubled; }; sizeof(Mystruct)=12; v c ly mt 32-bit word (4 byte, khng phi 1 byte) Con tr (pointer) Con tr tr n mt con tr khc CODE chara='z';//a='z'vgi s ach caa=8277 char*p=&a;//p=8277vgi s ach cap=6194 char**p2=&p;//p2=6194vach cap2s lmtcig Con tr void (void pointer) Con tr void dng tr n bt c mt kiu d liu no CODE voidincrease(void*data,intdataType) { switch(dataType) { casesizeof(char):

(*((char*)data))++;break; casesizeof(int): (*((int*)data))++;break; } } intmain() { charc=66;inta=-4; increase(&c,sizeof(char)); increase(&a,sizeof(int)); } Con tr hm (function pointer) Con tr hm dng tr n mt hm CODE intaddition(inta,intb) { returna+b; } intsubtraction(inta,intb) { returna-b; } int(*minuse)(int,int)=subtraction; intprimi(inta,intb,int(*functocall)(int,int)) { return(*functocall)(a,b); } intmain() { intm=primi(7,5,&addition); intn=primi(20,m,minuse); cout<<m<<endl;cout<<n<<endl; return0; } Hm ni tuyn (inline function) Hm khai bo vi t kha inline, trnh bin dch s chn ton b thn hm mi ni m hm c s dng. Vi cch ny, cc hm inline c tc thc thi cc nhanh, nn s dng vi cc hm thng xuyn phi s dng trong chng trnh. CODE inlinevoiddisplay(char*s) { cout<<s<<endl; } intmain() { display("Hello");return0; } Nhp xut vi tp tin CODE #include<fstream> #include<iomanip>

intnumber; ifstreaminf;ofstreamoutf; inf.open("input.txt"); outf.open("output.txt"); while(in>>number) outf<<"Nextis"<<setw(4)<<number<<endl; inf.close(); outf.close(); M mt file dng cho c nhp v xut CODE fstreamf; f.open("st.txt",ios::in|ios::out); mts ch haydng ios::innghalnhpvo ios:outnghalxutratptint utptin ios::appnghalthmd liuvotptin(appending) Tp tin header To mt tp tin header c tn l myfile.h #ifndef MYFILE_H #define MYFILE_H #endif trong tp tin cpp thm vo dng #include "myfile.h"

BI 3: NHC LI V LP C bn v lp CODE classDate{ intday; public: Date(int,inta=1); intmonth; voidsetDay(int); voidoutput(); }; intmain(){ Dated(6); d.month=3; d.setDate(25); d.output(); return0; } Date::Date(intday,intmonth){ this->day=day; this->month=month; } voidDate::setDay(intday){ this->day=day; } voidDate::output(){ cout<<day<<"/"<<month; } Hm khi to Chng ta c th vit mt hm khi to nh th ny CODE classStudent { stringname;intage; public: Student(stringname,intn):name(name),age(n) { } }; N tng ng vi CODE classStudent { stringname;intage; public: Student(stringname,intn) { (*this).name=name; this->age=n; } };

Hm bn (friend function) CODE classStudent{ public: intid; friendboolequal(constStudent&,constStudent&); }; intmain(){ Students1;s1.id=2; Students2;s2.id=3; cout<<equal(s1,s2); } boolequal(constStudent&s1,constStudent&s2){ return(s1.id==s2.id); } Overload ton t (operator overload) V d di s overload ton t == CODE classStudent{ public: intid; friendbooloperator==(constStudent&,constStudent&); }; intmain(){ Students1;s1.id=2; Students2;s2.id=3; cout<<((s1==s2)?"equal":"unequal"); } booloperator==(constStudent&s1,constStudent&s2){ return(s1.id==s2.id); } Overload ton t nhp v xut (input >> v output <<) Mi ngi u bit cin>>a l gi ton t nhp cin.operator>>(a) hoc operator>>(cin,a) Overload 2 ton t nhp v xut ny ht sc quan trng v sau. Nhn tin mi khi cp pht b nh, dng xong phi lun hy i thu hi li b nh cp pht. V v sau game ci u tin hng u l b nh, ng li rc. CODE classDate{ public: intday;intmonth; friendistream&operator>>(istream&,Date&); friendostream&operator<<(ostream&,constDate&); }; istream&operator>>(istream&ins,Date&d){ ins>>d.day; ins>>d.month; ins.get();//phixab m returnins; } ostream&operator<<(ostream&outs,constDate&d){ outs<<d.day<<"/"<<d.month;

returnouts; } intmain(){ Dated; cin>>d;cout<<d; Date*dt=newDate;//phitoobjectpointer,cpphtb nh cin>>*dt;cout<<*dt; deletedt;//phihyobjectpointer } Hm hy (destructor) CODE classmyclass{ public: int*p; myclass(); ~myclass(); }; intmain(){ myclassm; return0; } myclass::myclass(){ p=newint;//phicpphtb nh trnhsegmentationfault } myclass::~myclass(){ deletep; } Hm khi to sao chp (copy constructor CODE classDate{ public: intday;intmonth;char*special; Date(int,int,char*); Date(constDate&); ~Date(){ delete[]special;//bivchngtacpphtb nh chon } }; Date::Date(intday,intmonth,char*special){ this->day=day;this->month=month;this->special=special; } Date::Date(constDate&d){ this->day=d.day;this->month=d.month; this->special=newchar[strlen(d.special)+1];//cpphtb nh chon strcpy(this->special,d.special);//phidngstrcpyvichararray } intmain(){ Dated1(29,8,"birthday"); Dated2(d1); cout<<d2.special; return0; }

Ch v cp pht b nh iu g s xy ra khi chng ta khng th cp pht b nh ? V d chng ta vit 1 game RTS m mi phe tham chin c 10 t qun ? Gii quyt khi khng th cp pht b nh thnh cng Chng ta vn thng cp pht b nh nh sau CODE char*p;inti; cout<<"numberofelementuwant:"; cin>>i; p=newchar[i+1]; delete[]p; Nu chng ta khng th cp pht b nh ? CPP s nm (throw) ra mt ngoi l. C 2 cch x l chuyn ny Cch mt l dng t kha nothrow. V th CPP vn to ra mt pointer nhng l 0 CODE p=new(nothrow)char[i+1]; if(p==0)cout<<"Can'tallocatememory"; Cch hai l bt ci ngoi l y, l ngoi l std::bad_alloc CODE try{ p=newchar[i+1]; }catch(std::bad_alloc&mae){ cerr<<"failedtoallocatememory"<<mae.what(); exit(1); } Cp pht b nh trong C ng c ch m new v delete khng thi, cp pht vi cch ca C vn phi dng v sau y CODE char*p;inti; printf("numberofelementuwant:"); scanf("%d",&i); p=(char*)malloc(i+1); if(p==NULL)exit(1); free(p); hocchngtacth dngcalloc p=(char*)calloc(i,sizeof(char)); Ton t gn (assignment operator) CODE classBase{ public: Base&operator=(constBase&); friendbooloperator!=(constBase&,constBase&); private: char*c; }; Base&Base::operator=(constBase&src){ if(*this!=src){//toavoidself-assignment delete[]c;

c=newchar[strlen(src.c)+1]; strcpy(this->c,src.c); } return*this; } booloperator!=(constBase&b1,constBase&b2){ return(strcmp(b1.c,b2.c)); } Vchngtacth gitont ny Bases2=s1; Tha k (inheritance) Trong C c th sinh ra bug, trong C++ chng s c tha k. CODE classBase{ protected: intid; Base(intid){ this->id=id; } }; classSub:publicBase{ public: intcode; Sub(intcode,intid):Base(id){ this->code=code; } }; Hm o (virtual function) Hm Play trong lp MusicPlayer l mt hm o (virtual function) CODE classMusicPlayer{ public: virtualvoidPlay(){ cout<<"Playonwhat?"<<endl; } }; classDVD:publicMusicPlayer{ public: voidPlay(){ cout<<"PlayonDVD"<<endl; } }; intmain(){ MusicPlayerm;m.Play(); DVDd(2);d.Play(); } By gi chng ta s lm hm Play trong lp MusicPlayer l mt hm thun o (pure virtual function), ng thi lm lp MusicPlayer tr thnh mt lp tru tng (abstract class), chng ta s khng th to instance ca n c na CODE classMusicPlayer{

public: virtualvoidPlay()=0; }; classDVD:publicMusicPlayer{ public: voidPlay(){ cout<<"PlayonDVD"<<endl; } }; intmain(){ DVDd(2);d.Play(); } Chng ta to con tr tr n cc subclass ca n CODE MusicPlayer*m=newDVD(5);m->play(); Chng ta cung c th to mng cc con tr ca mt lp tru tng CODE classMusicPlayer...lmtlptrutng classDVD:publicMusicPlayer... classCD:publicMusicPlayer... MusicPlayer*m[2]; m[0]=newDVD(5);m[0]->play(); m[1]=newCD("Sony");m[1]->play(); Nhc li mt cht v mng cc k t (char array) CODE chardestArray[10];charsrcArray[]="panther"; strcpy(destArray,srcArray); strcpy(destArray,srcArray,strlen(srcArray)); strcat(s1,s2);//thm(append)s2vos2 strncat(s1,s2,n);//thm(append)nkt utincas2vos1 strlen(char*s);// di(length)cachararray,khngbaogm"endofchararraymaker" char*a;charb[];strcmp(a,b);//tr v 0nubng,-1nua<b,1nua>b atoi,atof,atollconvertmtchararraythnhinteger,floathaylong,3hmnytrongstdlib.h char*s="123.45"; inti=atoi(s); floatf=atof(s); Nhc li mt cht v chui (string) CODE usingstd::string; *khito(constructor) strings1;strings2("Helloboy");strings3(s2); strings4(s2,3,4);//saochpt kt th 3,saochp4kt strings5(8,'*');//khitochuigmtondu* *tont gn(assignment) strings4=s2;strings5.assign(s3); *sosnhchui(comparestring) if(s1==s2)//bygi cth dng==ri if(s1.compare(s2)) *cngchui

strings1,s2;s1+=s2;s1+='o'; s1.append(s2);//ynhus1+=s2 s1.append(s2,3,string::npos);//thmvos1t kt th 3nhts2 s1.insert(7,s2);//thms2vosaukt th 7cas1 *kchc (capacity) s.capacity()tr v kchc tia ifs.size()=15,s.capacity()=16(16-byte) ifs.size()=17,s.capacity()=32(two16-byte) *truyxutchui #include<stdexcept> try{ cout<<s.at(100); }catch(out_of_range&e){ cout<<"invalidindex"; }

BI 4: TEMPLATE Hm template Gi s chng ta cn vit mt hm tr v s nguyn ln nht gia 2 s CODE intmaximum(inta,intb) { return(a>b)?a:b; } Ri n s thc chng ta cng lm nh vy CODE doublemaximum(doublea,doubleb) { return(a>b)?a:b; } id: post-25916, class: postcolor div, Ri gi s nh vi lp Person chng ta cng phi lm nh vy (ton t > c overload) CODE Personmaximum(Persona,Personb) { return(a>b)?a:b; } C++ cung cp mt gii php cho vn ny, l template CODE template<classT>Tmaximum(Ta,Tb) { return(a>b)?a:b; } intmain() { inta=7;intb=5; cout<<maximum(a,b); return0 } template vi nhiu hn mt kiu d liu CODE template<classT,typenameU>voidfunc(Ta,Ub); Dng template vi mng CODE template<classT,intsize>voidprint(T(&a)[size]) { for(inti=0;i<size;i++)cout<<a[i]<<endl; } Lp template (template class) CODE template<classT>classpair { Tvalues[2]; public: pair(Tfirst,Tsecond) { values[0]=first;values[1]=second; } Tgetmaximum(); }; template<classT>Tpair<T>::getmaximum() { return(values[0]>values[1])?values[0]:values[1]; } Trong hm main CODE pair<int>myobject(155,36); myobject.getmaximum(); Tht tuyt, ng khng ? Vn khng n gin nh vy. au u Xem li hm template di y CODE template<classT>Tmaximum(Ta,Tb) { return(a>b)?a:b; } V d di y thc ra l ang so snh a ch b nh (memory address) ca 2 bin a v b CODE char*a="hello";char*b="world"; cout<<maximum(a,b); V d di y cng l ang so snh a ch b nh (memory address) ca 2 bin a v b

CODE inta[3],b[3]; cout<<maximum(a,b); Vy phi lm sao ? (Trong lp trnh, nhng vn tng nh nh nht th ny thc ra gy au u lm , nht l khi phi lm d n t 1000 words tr ln. M c bit ring lp trnh game ng nhng chuyn au u ny thng xuyn hn cc phn ngnh IT khc. Bin dch thnh cng, m ti sao n k cc vy n ?) Cu tinh xut hin, l mt tham chiu m tham chiu n mt con tr (a reference which refers to a pointer). y l dng au u nht ca tham chiu. A reference which refers to a pointer CODE int*p;//mtcontr pbnhthng int*&r=p;//thamchiurlnicknamemicap r=newint;//tngngvip=newint *r=5;//tngongvi*p=5 cout<<*p;//tng ngvicout<<*r V nh vy, vn kh khn vi d liu kiu mng c gii quyt. CODE template<classT>T*maximum(T*&a,T*&b) { return(*a>*b)?a:b; } intmain() { char*a="bb"; char*b="aa"; cout<<maximum(a,b); return0; } Lu l ch c "mt tham chiu m tham chiu n mt con tr" v "mt con tr m tr n mt con tr khc", ch khng th c nhng khi nim nh "mt tham chiu m tham chiu n mt tham chiu khc" hay "mt con tr m tr n mt tham chiu" u nh. Ht kh khn cha ? Cha u.

BI 5: TEMPLATE (TIP) Li au u Ta mun vit mt chng trnh tm kim phn t trong mt mng. Ta vit nh sau CODE template<classT>intsearch(Ta[],intn,Tkey) { intindex=0; while(index<n&&a[index]!=key)index++; if(index==n)return-1;elsereturnindex; } Sau trong hm main ta vit CODE char*list[]={"zero","one","two"};//thcralmng2chiuthi search(list,3,"two");// khng,lisosnhmemoryaddressnari Nhng ln ny vn phc tp hn nhiu. V d nu l mng cc Person l ng thm vn cp pht b nh na Gii quyt Chng trnh di y trnh by cch to mt lp mng template, vi cc chc nng to, thm, truy xut d liu, ton t []. c bit l gii quyt au u tm kim d liu trn v so snh memory address. Lu l khi to ta phi dng reference refers to pointer cp pht b nh CODE #include<iostream> usingnamespacestd; template<classT>classArray { T*array;intsize; public: Array(intn); ~Array(); voidsetValue(constT&,intn);//thitlpd liu T&getValue(intn);//truyxutd liu voidmakeArray(T*&arr,intn);//tomng T&operator[](inti);//tont []truyxutd liumng intseek(constT&key);//tmkimtrongmnggihm intsearch(constT*list,intsize,constTkey);//tmkimtrongmngcsn }; template<typenameT>Array<T>::Array(intn) { size=n; array=newT[size]; } template<typenameT>Array<T>::~Array() { delete[]array; } template<typenameT>voidArray<T>::setValue(constT&value,intn) { *(array+n)=value; } template<typenameT>T&Array<T>::getValue(intn) { return*(array+n);

} template<typenameT>voidArray<T>::makeArray(T*&arr,intn) { arr=newT[n]; } template<typenameT>T&Array<T>::operator[](inti) { return*(array+i); } template<typenameT>intArray<T>::seek(constT&key) { intindex=0; while((index<size)&&*(array+index)!=key)++index; if(index==size)return-1; elsereturnindex; } template<typenameT>intArray<T>::search(constT*list,intsize,constTkey) { intindex=0; while((index<size)&&*(list+index)!=key)++index; if(index==size)return-1; elsereturnindex; } classPerson { intage; public: Person(){age=0;} Person(intage){this->age=age;} intgetAge()const{returnage;} friendbooloperator!=(constPerson&p1,constPerson&p2) { returnp1.getAge()!=p2.getAge(); } friendostream&operator<<(ostream&os,constPerson&p) { os<<p.getAge()<<endl; returnos; } }; intmain() { Array<Person>a(3); a.setValue(Person(5),2); cout<<a[2]; Person*b; a.makeArray(b,4); for(inti=0;i<4;i++)*(b+i)=Person(i+2); cout<<a.seek(Person(5))<<endl; cout<<a.search(b,4,Person(4))<<endl; return0; } C v xong. Ht rc ri ri. Cha. Vn cn 2 rc ri na. Bn hy th vit ton t output << cho mt mng template class hay so snh gia hai mng

template class nh trn th xem. Bn s khng vit c u nu khng s dng ci ny: prototype template function (khai bo nguyn mu cho hm template) (Hc my ci in u ny lm g nh ? Lm g ? Hy th cho hai cu th trong mt game banh i din nhau. H c bao nhiu hnh ng c th lm c lc ? Chuyn bng ? La bng ? n ? special Zidane-style skill ? Mike Tyson skill ? Hai mng cc hnh ng y phi em ra m chi ln nhau. Bi th mang ting l Advance C++ nhng thc ra trong lp trnh game vn ch l newbie) prototype template function Chun b mt tp tin tn l array.h CODE #ifndefARRAY_H #defineARRAY_H #include<iostream> usingnamespacestd; template<classT>classArray; template<typenameT>boolequal(constArray<T>&,constArray<T>&); template<typenameT>ostream&operator<<(ostream&,constArray<T>&); template<classT>classArray { T*array;intsize; public: Array(intn); ~Array(); voidsetValue(constT&,intn); friendboolequal<>(constArray<T>&,constArray<T>&); friendostream&operator<<<>(ostream&,constArray<T>&); }; #include"array.cpp" #endif Chun b mt tp tin tn l array.cpp CODE template<typenameT>Array<T>::Array(intn) { size=n; array=newT[size]; } template<typenameT>Array<T>::~Array() { delete[]array; } template<typenameT>voidArray<T>::setValue(constT&value,intn) { *(array+n)=value; } template<typenameT>boolequal(constArray<T>&a1,constArray<T>&a2) { returna1.size==a2.size; } template<typenameT>ostream&operator<<(ostream&os,constArray<T>&a) { for(inti=0;i<a.size;++i)os<<*(a.array+i); returnos; }

Cui cng l main.cpp CODE #include"array.h" classPerson { intage; public: Person() { age=0; } Person(intage) { this->age=age; } intgetAge()const { returnage; } friendbooloperator!=(constPerson&p1,constPerson&p2) { returnp1.getAge()!=p2.getAge(); } friendostream&operator<<(ostream&os,constPerson&p) { os<<p.getAge()<<endl; returnos; } }; intmain() { Array<Person>a(3); a.setValue(Person(24),0); a.setValue(Person(15),1); a.setValue(Person(5),2); cout<<a; Array<Person>b(3); cout<<equal(a,b)<<endl; return0; } Gii thch: equal v operator<< u l hai hm bn, do hot ng cn c sn lp Array. Nhng lp Array mun bin dch c phi cn c hai hm ny. Do ta phi khai bo prototype ca hai hm ny trc. Nhng v y l 2 template function,nn khi khai bo li prototype ca chng ln th hai trong mt class template ( y l class Array) ta phi c ci k hiu ny <> Khi l mt prototype template function. Khi , thay v tp tin cpp cha thn hm include tp tin header cha nguyn mu ca hm, ta phi lm ngc li. K thut ny hiu v ng dng cc k rc ri nhng kh ni li p dng rt nhiu v sau, c bit khi lm cc game ln. Bin dch li m ny vi GCC Khng bt buc, nhng nn lm nu nh sau ny bn c nh lm vic vi game trong mi trng *nix v console. Hy em 3 tp tin ny (array.h, array.cpp, main.cpp) v th bin dch bng GCC trong Linux th xem. Nh to makefile. Trong trng bn ti ch yu lm vic bng GCC v VI trong *nix ch khng phi Window. Vic s dng cc b Visual Studio tuy khng b cm nhng khng c khuyn khch. V bi tp ln bi thi u phi submit nguyn project km makefile bin dch trong mi trng *nix ht. Vit operator overload v copy constructor

Trong phn trc ta xem cc v d dng cch tham chiu m tham chiu n con tr Trong phn ny chng ta s overload ton t = v vit copy constructor cng s dng li cch ny, m khng phi dng n prototype template function CODE #include<iostream> #include<string> usingnamespacestd; template<typenameT> classArray { public: intsize; T*elems; Array(int); Array(constArray<T>*&); voidsetValue(constT&,inti); T&getValue(intn); Array<T>&operator=(constArray<T>*&); friendbooloperator!=(constArray<T>&,constArray<T>&); }; template<typenameT> Array<T>::Array(intsize) { elems=newT[size]; } template<typenameT> voidArray<T>::setValue(constT&value,inti) { *(elems+i)=value; } template<typenameT> T&Array<T>::getValue(inti) { return*(elems+i); } template<typenameT> Array<T>::Array(constArray<T>*&src) { size=src.size; elems=newT[size]; for(inti=0;i<size;i++) *(elems+i)=*(src.elems+i); } template<typenameT> Array<T>&Array<T>::operator=(constArray<T>*&src) { if(*this!=src)//toavoidself-assignment { size=src.size; elems=newT[size]; for(inti=0;i<size;i++) *(elems+i)=*(src.elems+i); } return*this; } template<typenameT>

booloperator!=(constArray<T>&a1,constArray<T>&a2) { if(a1.size!=a2.size)returntrue; elsefor(inti=0;i<a1.size;i++) if(*(a1.elems+i)==*(a2.elems+i))returnfalse; returntrue; } intmain() { Array<string>a(2); a.setValue("hello",0); a.setValue("world",1); Array<string>b(3); b=a; cout<<b.getValue(0)<<endl; cout<<b.getValue(1)<<endl; return0; }

BI 6: TEMPLATE (TIP THEO) Trnh bin dch v template Trong bi trc chng ta thy mt iu hi l l, l file header array.h c ch th #include file source array.cpp. Ti sao nh vy ? Khi trnh bin dch gp template, n kim tra c php, nhng khng bin dch ngay. V d n gp template<class T> n khng th bin dch v n khng bit kiu d liu ca T. Khi n gp instance u tin ca template, v d template<int> n bin dch v chng ta c phin bn vi kiu d liu int ca template. Khi n gp instance th hai ca template, v d template<double> n cng li bin dch v chng ta c phin bn th hai ca template, phin bn vi kiu d liu double. Vn vn. Thng thng chng ta vit nh ngha lp v nguyn mu cc hm ca lp file header (ui .h) ri mi vit thn cho cc hm mt file source (ui .cpp), m file cpp ny include lun file header . Template phi lm ngc li. V l do ni trn, c nh ngha lp, nguyn mu cc hm ln thn ca cc hm ca mt lp template phi c bin dch cng nhau. Do khi tch ri nh ngha ca mt lp template ra cha trong mt file header ring, file header phi include file source cha thn cc hm ca lp template , ri mt file no khc mun dng template phi include ci file header . y cn mt phn na v export, ti ct i. C nhiu th sau ny ti cng s ct i, nhm gim ti cho chng trnh xung n mc ti thiu nht c th c. Nhng an tm l nhng th quan trng nht u c y . Dng t kha no, class hay typename V c bn, s khc bit gia chng l khng r rng, c 2 u c cng ngha v cng cho kt qu nh nhau, bn mun dng t kha no cng c. Nhng c lc bn phi dng t kha typename, v d CODE template<typenameT>classThing{ T::SubType*ptr; }; Chng ta mun khai bo 1 con tr thuc kiu SubType ca T, nhng C++ s hiu l chng ta mun nhn gi tr SubType ca kiu T vi ptr Lc ny chng ta bt buc phi dng t kha typename CODE template<typenameT>classThing{ typenameT::SubType*ptr; };

Chuyn mn ha template (template specialization) Gi s ta c mt lp template template<class T>class pair{} Khi ta to mt instance bng cch khai bo c th kiu ca T, v d l int, tc l ta chuyn mn ha (specialization) lp template pair<int> myobject(155,36); i khi ta mun lp template to ra nhng instance c th thc hin nhng cng vic c th ring i vi mt loi d liu c th no , ta dng chuyn mn ha c th (explicit specialization) Trong v d di y ta mun ring i vi kiu d liu c th l int th lp template c mt hm tr v phn d gia hai s nguyn, cn vi cc kiu d liu khc th n tr v 0 CODE template<classT> classpair{ Tvalue1,value2;

public: pair(Tfirst,Tsecond){ value1=first;value2=second; } Tmodule(){return0;} }; //vitlinhnghalpchuynmnhachokiud liuint template<> classpair<int>{ intvalue1,value2; public: pair(intfirst,intsecond){ value1=first;value2=second; } intmodule(); }; //hmmodulednhringcholpchuynmnha template<> intpair<int>::module(){ returnvalue1%value2; } intmain(){ pair<int>myints(100,75); cout<<myints.module()<<endl; pair<float>myfloats(100.0,75.0); cout<<myfloats.module()<<endl; return0; }

p kiu d liu (casting) trong C++ Trong C chng ta p kiu d liu nh sau int n=(int)45.87; Trong C++ c 1 cch p kiu d liu nh sau int i = static_cast<int>(45.87); Cho ra kt qu nh nhau (tm ch cn bit th) Chng ta s cn quay tr li vi casting trong C++ sau Din dch i s (argument deduction) Xem li hm template di y template <typename T> T max(T a, T b) Kiu d liu ca 2 i s (argument) a v b s c quyt nh bi kiu d liu ca 2 tham s (parameter) truyn vo hm ny. V 2 i s ny cng l kiu T, nn 2 tham s ny phi cng mt kiu. C++ khng c t ng chuyn kiu y. V d max(7, 5); //hp l, T lc ny l kiu int, 2 tham s cng kiu int max(7, 5.2); //khng hp l, T lc ny l kiu int (kiu d liu ca tham s c truyn trc tin, nhng 2 tham s th mt ci kiu int, mt ci kiu double C 2 cch x l chuyn ny Cch 1: casting (p kiu) tham s u tin max(static_cast<double>(7), 5.2); //lc ny T l kiu double, 2 i s u cng kiu double Cch 2: explicit specialization (chuyn mn ha c th) cho T thnh double max<double> (7, 5.2); i s ca template (template argument) template thng c cc i s l typename T (vi T l kiu d liu cha bit) Nhng thc ra template cng c cc i s l cc kiu d liu bit

i s kiu primitive, v d kiu int CODE template<typenameT,intsize> classArray{ T*array; public: Array(); }; template<typenameT,intsize>Array<T,size>::Array(){ array=newT[size]; } intmain(){ Array<string,5>a; return0; } i s l mt lp template khc CODE #include<iostream> #include<string> usingnamespacestd; template<typenameT> classArray { T*array; public: Array(); }; template<typenameT>Array<T>::Array() { array=newT; } template<typenameT,typenameU=Array<typenameV>,intsize> classStack { U*elems; public: Stack(); }; template<typenameT,typenameU=Array<typenameV>,intsize> Stack<T,U,size>::Stack() { elems=newU[size]; } intmain() { Stack<string,Array<double>,5>a; return0; } Cn my phn na, nhng rt cao v t dng v sau trong lp trnh game, m ch yu cho lp trnh bc thp, phn cng, h iu hnh, nn ti b, nh th ny nhc u v kh nh ri. Cc bc hc xong template ri , nm r tt c cc k thut v template chun b cho hc STL v sau.

Lm ci bi tp ch nh. n gin thi: lp trnh mt danh sch lin kt n dng template, cc php thm, xa, sa, truy xut. C sn ci chng trnh mu di ny. Chng trnh ny cc yu, khng c xa, hy Chng trnh cn cc bc b sung . CODE template<typenameT>classNode { Tdata;Node<T>*next; public: Node<T>(Tdata){(*this).data=data;(*this).next=0;} TgetData(){returndata;} voidsetData(Tdata){(*this).data=data;} Node<T>*getNext(){returnnext;} voidsetNext(Node<T>*next){(*this).next=next;} }; template<typenameT>classList { Node<T>*front;Node<T>*rear;Node<T>*current; public: List<T>(){(*this).front=(*this).rear=(*this).current=0;} List<T>(constList<T>&l()){ (*this).front=(*this).rear=(*this).current=0; Node<T>*temp=new(nothrow)Node<T>;if(temp==0)exit(1); temp=l.front; while(temp!=0){ insertRear(temp->getData()); temp=temp->getNext(); } } ~List<T>(){ Node<T>*temp=new(nothrow)Node<T>;if(temp==0)exit(1); while(front!=0){ temp=front; front=(*front).next; deletetemp; } } voidinsertFront(Tdata){ Node<T>*temp=new(nothrow)Node<T>;if(temp==0)exit(1); (*temp)->setData(data); if(front==0)rear=temp; elsetemp->setNext(front); front=temp; } voidinsertRear(Tdata){ Node<T>*temp=new(nothrow)Node<T>;if(temp==0)exit(1); (*temp)->setData(data); if(rear==0)front=temp; elserear->setNext(temp); rear=temp; } voidreset(){if(front!=0)current=front;} voidnext(){if(current!=0)current=current->getNext();} TgetCurrentData(){if(current!=0)returncurrent->getData();} boolendOfList(){return(current==0);}

};

BI 7: CONST, STATIC, EXCEPTION, CASTING (BIN HNG, BIN TNH, NGOI L, P KIU) CONST const int p v int const p l nh nhau int* const p ngha l mt hng s loi con tr m tr n mt bin s kiu nguyn, ngha l bn khng th thay i con tr ny tr n mt ni khc c na CODE inta=3;intb=5; int*constp=&a; p=&b;//khnghpl

const int* p ngha l mt bin s loi con tr m tr n mt hng s kiu nguyn, ngha l bn c th thay i con tr ny tr n mt ni khc, nhng khng th thay i d liu ni n tr n CODE inta=3;intb=5; constint*p=&a; p=&b;//hpl *p=6;//khnghpl

const int *& p ngha l mt tham chiu m tham chiu ti mt bin s loi con tr m tr n mt hng s kiu nguyn int const *& p ngha l mt tham chiu m tham chiu ti mt hng s loi con tr m tr n mt bin s kiu nguyn Mt bin s const ngha l bin phi c gn gi tr ngay lc khai bo v gi tr y vnh vin khng thay i (ci ny qu ph bin ri) Mt hm s const ngha l hm s s khng thay i gi tr ca bt c tham s no ca n. Mt hm s phi c khai bo const nu n c t nht mt tham s const CODE classTree{ intage; public:intgetAge()const{returnage;} friendostream&operator<<(ostream&os,constTree&t) {os<<t.getAge();returnos;} }; Hm s getAge phi l mt hm s const bt k hm s khc dng tham s const Tree c th s dng hm s getAge Hm s tr v const V d chng ta vit mt hm nh sau CODE int&hello() { inttemp=5; returntemp; } V mt ai c th li dng gn gi tr cho n, rt nguy him CODE

hello()=3; Nn chng ta phi thay i n tr v const CODE constint&hello() { inttemp=5; returntemp; } Bo v tham s Hn bn cn nh v d ny ch CODE voidadd10(int*a){ *a=*a+10; } add10(&n); ngha y l, mt hm hon ton c th thay i gi tr ca tham s nu ta truyn vo n a ch ca bin . M vic truyn a ch l vic phi lm. V i khi khng th khng truyn a ch, v d kiu mng CODE voiddosomething(char*a){...} char*m="hello"; dosomething(m); Khi ta dng t kha const ngn vic hm thay i gi tr ca i s CODE voiddosomething(constchar*a){...} char*m="hello"; dosomething(m); STATIC Mt bin s const ngha l bin phi c gn gi tr ngay lc khai bo v gi tr y vnh vin khng thay i Mt bin s static ngha l bin phi c gn gi tr ngay trc khi to mt instance ca mt lp v gi tr y c thay i, nhng ch c duy nht mt bin static y tn ti i vi tt c instance ca lp CODE classMyClass { public: staticinti; }; intMyClass::i;//tnticlp,khngph thucinstance intmain() { MyClass::i=30; MyClassx,y; x.i=26; cout<<y.i<<endl; }

Mt hm s static ngha l hm s y c th c hot ng lp m khng cn to i tng ca lp

CODE classMyClass { public: staticvoidprint(char*s) { cout<<s<<endl; } }; intmain() { MyClass::p("Hello"); return0; } Ngoi l (Exception) Hm di y c th nm ra bt c ngoi l no CODE voidin(inta);//ch cnkhaibobnhthng Hm di y khng th nm ra bt c ngoi l no CODE voidin(inta)throw(); Khng nh Java, trong C++ bt c lp no cng c th l lp ngoi l (exception class), v cng khng cn phi l lp con ca lp no ht Chng ta bt ngoi l bng try catch nh Java CODE classDivideByZero { public: voidmsg() { cout<<"Cannotdividebyzero"<<endl; } }; intdivide(inta,intb)throw(DivideByZero) { if(b==0)throwDivideByZero(); returna/b; } intmain() { try { inta=divide(3,0); } catch(DivideByZeroe) { e.msg(); } return0; }

Khi chng ta bt c mt ngoi l, chng ta c th nm n ra bt li mt ln na bng throw; CODE classDivideByZero { public: voidmsg() { cout<<"Cannotdividebyzero"<<endl; } }; intdivide(inta,intb)throw(DivideByZero) { if(b==0)throwDivideByZero(); returna/b; } intmain() { try { try { inta=divide(3,0); } catch(DivideByZeroe) { e.msg();throw;//nmra btlilnhai } } catch(DivideByZero) { cout<<"Stopped!That'senough"<<endl; } return0; } Chng ta c th nm ra v bt li bt c ci g ch khng phi ch mt lp CODE intmain() { ints[5]; try { for(inti=0;i<6;i++) { if(i>=5)throw"Outofrange"; s[i]=i; } } catch(char*c) { cout<<c<<endl; } return0;

} Chng ta c th nm ra nhiu th bng mt ch th try v bt li tt c mi th, mi th mt ch th catch khc nhau CODE intmain() { try { intsize;cin>>size; if(size>10)throw"Sobig"; elsethrowsize; } catch(intn) { cout<<n<<"isnothere"<<endl; } catch(char*c) { cout<<c<<endl; } return0; } Nu c ngoi l no khng b bt, hm c bit void terminate() s c gi ngay lp tc chm dt chng trnh Chng ta c th bt tt c cc loi ngoi l x l ch vi mt ch th catch(...) CODE intmain() { try { intsize;cin>>size; if(size>10)throw"Sobig"; elsethrowsize; } catch(...) { cout<<"throwexception"<<endl; } return0; } p kiu (Casting) p kiu theo cch ca C int n=(int)45.87; static_cast (p kiu tnh) Kim tra lc bin dch (compile time) int n=static_cast<int>(45.87); int n=static_cast<int>(hello); //lc bin dch s pht sinh li dynamic_cast (p kiu ng) Kim tra lc thc thi (runtime) Lp dng vi dynamic_cast phi c hm o. downcast p kiu cc con tr v cc i tng t kiu lp cha thnh kiu lp con, c gi l downcast. y l mt kiu casting quan trng, dng nhiu v sau trong RTTI. C 2 cch thc hin downcast bng static_cast

CODE classBase{}; classDerived:publicBase{}; Base*b=newDerived; Derived*d=static_cast<Derived*>(b); bng dynamic_cast CODE classBase{virtualvoidfunc(){}}; classDerived:publicBase{}; Base*b=newDerived; Derived*d=dynamic_cast<Derived*>(b); upcast p kiu cc con tr v cc i tng t kiu lp con thnh kiu lp cha, c gi l upcast. upcast him dng hn downcast. C 2 cch thc hin upcast bng static_cast CODE classBase{}; classDerived:publicBase{}; Derived*d=newDerived; Base*b=static_cast<Base*>(d); bng dynamic_cast CODE classBase{virtualvoidfunc(){}}; classDerived:publicBase{}; Derived*d=newDerived; Base*b=dynamic_cast<Base*>(d); const_cast (p kiu hng) const_cast dng ch yu vi cc con tr const_cast dng thay i mt bin s thnh mt hng s (thm t kha const vo) CODE inta=3; int*b=&a; *b=8;//hpl constint*c=const_cast<int*>(b); *c=5;//khnghpl cout<<*c; cout<<a; const_cast dng thay i mt hng s thnh mt bin s (g t kha const ra) CODE constinta=3; constint*b=&a; *b=8;//khnghpl int*c=const_cast<int*>(b); *c=5;//hpl cout<<*c; cout<<a;

reinterpret_cast (p kiu thng dch li) reinterpret_cast s p kiu bt c con tr hay i tng no m khng h c s kim tra no c. Khng khuyn khch dng v by gi ta cng cha phi dng, s hc sau.

BI 8: STL - SEQUENTIAL CONTAINER Yu cu: hc xong mn cp trc d liu v gii thut c bn hoc tng ng c kin thc c bn v cc cu trc d liu ng nh danh sch lin kt (linked list), hng i (queue), ngn xp (stack), tp hp (set), nh x (map) v cc gii thut tm kim, sp xp c bn. STL (Standard Template Library) l mt b th vin v cng hu dng ca C++ dng lm vic vi cc cu trc d liu ph bin nh danh sch, hng i, ngn xp v cc php ton ch yu vi cc cu trc d liu ny nh tm kim, sp xp, truy xut, thm, xa, sa. STL bao gm *Cc container (cc b lu tr d liu) l cc cu trc d liu ph bin template ha dng lu tr cc kiu d liu khc nhau. Cc container chia lm 2 loi: -sequential container (cc b lu tr d liu tun t) bao gm list, vector v deque -associative container (cc b lu tr d liu lin kt) bao gm map, multimap, set v multiset *Cc iterator (cc con tr d liu) l cc con tr tr n cc phn t trong cc b lu tr *Cc algorithm (cc thut ton lu tr d liu) l cc hm ph bin lm vic vi cc b lu tr nh thm, xa, sa, truy xut, tm kim, sp xp *Cc function object (cc i tng hm) l cc hm v php ton ph bin lm vic vi cc phn t c lu tr cng nh cc b lu tr v cc thut ton lu tr nh cng, tr, nhn, chia, so snh *Cc adapter (cc b tng thch) Cc adapter chia lm 3 loi -container adapter (cc b tng thch lu tr) bao gm stack, queue v priority_queue -iterator adapter (cc b tng thch con tr) -function adapter (cc b tng thch hm) Trc tin ta hc v cc container. LIST CODE #include <list> list rong STL l danh sch lin kt i, khng h tr random access (truy xut d liu bt k) Ngha l nu bn mun truy xut mt phn t bt k trong list th bn phi truy xut t phn t u tin hoc phn t cui cng ca list ri truy xut dn n phn t Khi to sao chp list c th khi to sao chp t mng, t list khc hoc t cc container khc CODE int a[10]; list<int> list1(a+2,a+7); list<int> list2(list1.begin()++,--list1.end());

Cc hm thng dng ca list CODE void push_front(T element): a mt phn t vo u list void push_end(T element): a mt phn t vo cui list void pop_front(): g phn t u list ra void pop_end(): g phn t cui list ra iterator begin(): tr v iterator tr n phn t u list iterator end(): tr v iterator tr n phn t cui list

Vi d di chng ta to mt list, a phn t vo v truy xut phn t

CODE list<string> list1; list1.push_back("Zebra");list1.push_back("Penguin");list1.push_front("Lion"); list<string>::iterator i; for(i=list1.begin();i!=list1.end();++i) cout<<*i<<endl; Ton t * c dng ly gi tr ca iterator *i: tr v gi tr c tr ti bi iterator i, y l cc phn t ca list1 Nu chng ta mun mt list cha nhiu list, ta ch cn khai bo CODE list<list<string> > listOfList;

Nu list c khai bo const, chng ta phi dng const_iterator thay v iterator CODE const list<string> list1; list<string>::const_iterator i = list1.begin();

Cc hm thng dng khc ca list CODE int n=list1.size();//tr v s phn t ca list bool b=list1.empty();//kim tra list, nu rng (khng c phn t) th tr v true, ngc li tr v false list1.insert(list1.begin(),"Seadog");//chn phn t "Seagon" vo v tr u list list1.insert(++list1.begin(),2,"Seadog");//chn phn t "Seagon" vo mt v tr c th list1.erase(list1.begin());//xa mt phn t mt v tr c th list1.erase(++list1.begin(),3);//xa 3 phn t bt u t mt v tr c th list1.clear();//xa tt c cc phn t list1.remove("Zebra");//tm kim v xa phn t "Zebra" list1.sort();//sp xp tng dn (ascending) list1.reverse();//sp xp gim dn (descending) list1.resize(int);//thit lp s phn t mi ca list iterator i=list1.find(++list1.begin(),--list1.end(),"Penguin");//tm kim phn t "Penguin", bt u mt v tr c th kt thc mt v tr c th khc, tr v iterator tr n phn t ny. Nu khng tm thy, hm ny tr v v tr kt thc, y l --list1.end()

Cc hm vi hai list CODE list<string> list1; list<string> list2; list1.splice(--list1.end(),list2,list2.begin()); //splice(cut v paste) mt phn t t v tr list2.begin() ca list2 n v tr --list1.end() ca list1 list1.splice(--list1.end(),list2); //splice(cut v paste) tt c phn t ca list2 n v tr --list1.end() ca list1 list1.merge(list2);//merge 2 list, ngha l list1 = list1 + list2; list2.swap(list1);//swap 2 list, ngha l temp = list2;list2 = list1;list1 = temp;

VECTOR CODE

#include <vector> vector ging list ngoi tr -cho php random access, vi operator[], ngha l v[5], v[6], etc nh mng -c ti u ha vi cc php ton pha ui (rear operations) -khng c sn cc hm push_front,pop_front,splice,sort,merge,reserve CODE vector<int> v; v.push_back(5); cout<<v[0];

DEQUE CODE #include <deque> deque ging list ngoi tr -cho php random access, vi operator[], ngha l d[5], d[6], etc nh mng -c ti u ha vi cc php ton pha u (front operations) -khng c sn cc hm splice,sort,merge,reserve CODE deque<int> d; d.push_front(5); cout<<d[0];

ALGORITHM CODE #include <algorithm> Do vector v deque khng c sn cc hm splice,sort,merge,reserve nn nu ta mun s dng cc chc nng ny vi vector v deque ta phi dng cc hm trong th vin algorithm Sp xp CODE #include <algorithm> vector<int> v; sort(v.begin(),v.end());//sp xp tng dn (ascending) reverse(v.begin(),v.end());//sp xp gim dn (descending)

Sao chp CODE int a[]={1,2,3,4}; vector<int> v; v.resize(3); copy (a,a+3,v.begin());//sao chp 3 phn t t mng a vo vector v

Merge v swap CODE

vector<int> v, v2; merge(v1.begin(),v1.begin()+5,++v2.begin(),v2.end(),v1.begin());//hp 2 phn d liu, phn mt t v1.begin() n v1.begin()+5, phn hai t ++v2.begin() n v2.end(), sau chp tt c vo v1 bt u t v1.begin() swap(v1, v2);

CC PHN T L CON TR Gi s ta c lp Person vi hm khi to Person(char* name) CODE a mt phn t Person vo vector: vector<Person> v;v.push_back(Person("C")); a mt phn t con tr Person vo vector, ta phi dng new cp pht b nh: vector<Person*> vp;vp.push_back(new Person("M")); truy xut phn t vector<Person>::iterator i; for(i=v.begin();i!=v.end();++i) cout<<*i<<endl; truy xut phn t con tr vector<Person*>::iterator ip; for(ip=vp.begin();ip!=vp.end();++ip) cout<<**ip<<endl; *i: tr v gi tr c tr ti bi iterator i, y l cc phn t ca vector v vector<Person>::iterator i; (*i) tr v Person **ip: tr v gi tr ca cc con tr c tr ti bi iterator i, y l cc phn t con tr ca vector vp vector<Person*>::iterator ip; (*ip) tr v Person* nh vy (**ip) tr v *(Person*)

BI 9:FUNCTION OBJECT (I TNG HM) Function object Mt function object (i tng hm) l mt object (i tng) c s dng nh mt function (hm). Mt Mt function object l mt instance ca mt lp m lp phi c t nht mt hm tha -quyn truy xut phi l public -phi l mt hm thnh vin, khng phi l mt hm friend -khng phi l mt hm static -c khai bo operator() V d ta vit mt hm bnh thng nh sau CODE voidiprintf(inti)const { cout<<i<<endl; } By gi ta s vit mt lp nh sau CODE classiprintf { public: voidoperator()(inti)const { cout<<i<<endl; } }; Instance ca lp ny l mt object c gi l function object, l mt object c s dng nh mt function. S dng nh th no ? CODE iprintfx; x(5); hoc CODE iprintf()(5); Khi ta gi iprintf()(5) ngha l chng ta ang gi n operator() ca lp iprintf function object cn c gi l mt functor hay mt functional. T y khi cp n function object s dng functor. V d di y l mt lp c nhiu hn mt operator() CODE classiprintf { inti; public:iprintf(inti):i(i){} public: voidoperator()()const { cout<<i<<endl; } voidoperator()(inti)const

http://river.congdongso.com/advc++/bai9.htm

{ cout<<"Integer:"<<i<<endl; } voidoperator()(floatf)const { cout<<"Float:"<<f<<endl; } }; intmain(intargc,char**argv) { iprintfx(20); x(); x(5);//gi s khngcoperator()(inti),cunys gioperator()(floatf) x(2.3);//gi s khngcoperator()(floatf),cunys gioperator()(inti)vii=2 x("something");//li return0; } Tng t thay v iprintf(5); x(7); chng ta cng c th gi iprintf(5)(7); C mt iu ch v d trn l nu cng tn ti operator()(int i) v operator()(float f) th cu lnh x(2.3); s bo li ambiguous (nhp nhng) gia hai hm. C mt cch n gin l vit li thnh x((float)2.3); Predicate Predicate c mt nh ngha khc phc tp hn. y ch nu iu cn thit nht c lin can n chng trnh. Mt predicate c cp n y l mt function hoc mt functor c iu kin gi tr tr v ng hoc sai hoc mt gi tr c th chuyn kiu thnh ng hoc sai. Trong C/C++, ng c ngha l khc 0 v sai c ngha l bng 0 V d hm sau y l mt predicate CODE doubletruefalse(doublen) { returnn; } Mt s hm thng dng trong algorithm Hm find CODE vector<int>v; v.push_back(4);v.push_back(3);v.push_back(2); vector<int>::iteratori=find(v.begin(),v.end(),3); if(i!=v.end())cout<<*i; Hm find tm t phn t v.begin() n phn t v.end() v tr v iterator tr n phn t c gi tr l 3, nu khng tm thy s tr v v.end() Hm find_if CODE intIsOdd(intn) { returnn%2; } intmain() { list<int>l; l.push_back(4);l.push_back(5);l.push_back(2);

http://river.congdongso.com/advc++/bai9.htm

list<int>::iteratori=find_if(l.begin(),l.end(),IsOdd); if(i!=l.end())cout<<*i; } Hm find_if tm t phn t v.begin() n phn t v.end() v tr v iterator tr n phn t c gi tr tha predicate, nu khng tm thy s tr v v.end() Lu , lc ny IsOdd ng vai tr l mt predicate, xc nh xem phn t ca list c l s l hay khng (tc l khi a vo lm tham s ca hm IsOdd c tr v mt s khc 0 hay khng) Chng ta vit li predicate ny bng cch dng functor CODE classIsOdd { public: booloperator()(intn)const { returnn%2; } }; intmain() { list<int>l; l.push_back(4);l.push_back(5);l.push_back(2); list<int>::iteratori=find_if(l.begin(),l.end(),IsOdd()); if(i!=l.end())cout<<*i; } Hm equal trn chng ta mi xt cc v d vi predicate c mt i s, ta xt mt hm khc ca algorithm dng predicate nhiu hn mt i s, hm equal CODE classcompare { public: booloperator()(inti,intj)const { returni==j; } }; intmain() { comparec; inta[]={1,2,3,4,5}; list<int>l(a,a+3);//listtphnt hnmng cout<<equal(l.begin(),l.end(),a,c)<<endl; a[2]=6; cout<<equal(l.begin(),l.end(),a,c)<<endl; return0; } Hm equal so snh tng phn t ca list t phn t l.begin() n phn t l.end() vi tng phn t tng ng ca mng a sao cho mi cp phn t u tha predicate l c, tr v l true nu tng cp phn t so snh vi nhau u cho gi tr true (khng cn quan tm n s lng phn t c tng ng khng) Nhng ch cn mt cp tr v false th hm s tr v false

http://river.congdongso.com/advc++/bai9.htm

Hm search Hm search tm v tr ca mt chui con trong mt chui ln hn, nu tm thy th tr v iterator tr n v tr ca chui con trong chui ln. Hm ny c hai phin bn CODE inta[]={3,4,5}; vector<int>v; for(inti=0;i<10;i++)v.push_back(i); vector<int>::iteratoriv=search(v.begin(),--v.end(),a,a+2); if(iv!=--v.end())cout<<iv-v.begin(); Phin bn th nht tm v tr ca chui con t phn t c v tr a+0 n phn t c v tr a+2 trong chui ln hn t phn t c v tr v.begin() n phn t c v tr --v.end() Nu khng tm thy th tr v v tr --v.end() Trong on m trn c mt iu ng ch l iv-v.begin Lu l hm search tr v mt iterator, iterator ny l iv = v.begin() + v tr ca chui con. Do n gin v tr ca chui con = iv-v.begin() CODE classcompare { public: booloperator()(inti,intj)const { returni==j+1; } }; intmain() { inta[]={3,4,5}; vector<int>v; for(inti=0;i<10;i++)v.push_back(i); vector<int>::iteratoriv=search(v.begin(),v.end(),a,a+2,compare()); if(iv!=v.end())cout<<iv-v.begin(); return0; } Phin bn th hai s phi cn n mt predicate c hai i s ging nh hm equal. Phin bn th hai tm v tr ca chui con t phn t c v tr a+0 n phn t c v tr a+2 trong chui ln hn t phn t c v tr v.begin() n phn t c v tr --v.end() sao cho tng cp phn t tha compare() ( y l iu kin phn t ca v = phn t ca a + 1). Nu khng tm thy th tr v v tr -v.end() Tng t nh hm search ny l hm find_end, nhng thay v tr v v tr u tin ca chui con xut hin trong chui ln th li tr v v tr cui cng ca chui con xut hin trong chui ln. Hm for_each Hm for_each dng duyt tng phn t trong mt chui cc phn t cho trc Dng for_each in ra cc phn t, v d CODE voiddisplay(conststring&s){cout<<s<<endl;} list<string>l;l.push_back("hello");l.push_back("world"); for_each(l.begin(),l.end(),display); Tng t dng vi mt functor CODE template<typenameT>classOutput

http://river.congdongso.com/advc++/bai9.htm

{ public: voidoperator()(constT&t){cout<<t<<endl;} }; intmain(intargc,char*argv[]) { list<string>l;l.push_back("hello");l.push_back("world"); for_each(l.begin(),l.end(),Output<string>()); } Hm count Hm count dng m s lng phn t trong mt chui cc phn t cho trc CODE list<string>l;l.push_back("hello");l.push_back("world"); cout<<(int)count(l.begin(),l.end(),"hello")<<endl; Hm count_if Hm count_if dng m s lng phn t tha mt iu kin no trong mt chui cc phn t cho trc, hm cn mt predicate mt i s CODE classIsOdd { public: booloperator()(intn)const{return(n%2)==1;} }; intmain(intargc,char*argv[]) { list<int>l;for(inti=0;i<10;i++)l.push_back(i); cout<<(int)count_if(l.begin(),l.end(),IsOdd())<<endl; } Ton bi chng ta hc v predicate v th vin algorithm, cn mt s hm s hc sau. C mt iu ng lu l predicate mt i s v hai i s. S lng i s ca predicate c gi l hng (arity) ca predicate. Bit s iu ny v chun b cho bi tip theo.

http://river.congdongso.com/advc++/bai9.htm

BI 10:TH VIN FUNCTIONAL CODE #include<functional> Hng ca mt predicate C nhiu s mp m do t ng ngha gia cc khi nim ton hc trong c hai ngn ng ting Vit v ting Anh, do nh ngha sau ch mc c gng chnh xc nht c th c: S ton t (operand) ca mt php ton (operator), tng ng l s i s (argument) ca mt hm (function), c gi l hng (arity) ca php ton hay hm Tng t, s ton t (operand) ca mt biu thc (expression), tng ng l s i s (argument) ca mt i tng hm (functor), c gi l hng (arity) ca biu thc hay i tng hm V d Unary (n nguyn, n phn, mt ton hng, mt ngi) n! (giai tha ca n) l mt unary operator n! l mt unary expression, ch bao gm mt unary operator int giaithua(int n) l mt unary function mt object ca class giaithua{int operator()(int n)} l mt unary functor Binary (nh nguyn, nh phn, hai ton hng, hai ngi) a + b l mt binary expression, ch bao gm mt binary operator int addition(int a,int b) l mt binary function mt object ca class addition{int operator()(int a,int b)} l mt binary functor Ternary (tam nguyn, tam phn, ba ton hng, ba ngi) b * b 4 * a * c l mt ternary expression, bao gm mt unary operator v ba binary operator double delta(double a, double b,double c) l mt ternary function mt object ca class delta{ double operator()(double a, double b,double c)} l mt ternary functor n-ary (a nguyn, a phn, nhiu ton hng, nhiu ngi) Tng t nh trn, ngoi ra cn c nhiu t gc Latin khc nh quaternary (bn ton hng) quinary (nm ton hng) gi chung l nhiu ton hng. Hng ca predicate tc l hng ca function hay functor m ng vai tr predicate. Nh v d trn, addition l mt binary predicate, delta l mt ternary predicate Cu trc unary_function trong th vin functional Trong th vin functional nh ngha sn cu trc unary_function CODE template<classArg,classResult> structunary_function { typedefArgargument_type; typedefResultresult_type; }; unary_function l cu trc nh ngha sn cho tt c unary function v unary functor vi Arg l kiu d liu ca i s v Result l kiu tr v ca hm c operator() Chng ta vit li lp IsOdd, nh ngha n l mt unary_function CODE classIsOdd:publicunary_function<int,bool> { public: booloperator()(intn)const { returnn%2; } };

Cu trc binary_function trong th vin functional Tng t, trong th vin functional nh ngha sn cu trc binary_function CODE template<classArg1,classArg2,classResult> structbinary_function { typedefArg1first_argument_type; typedefArg2second_argument_type; typedefResultresult_type; }; binary_function l cu trc nh ngha sn cho tt c binary function v binary functor vi Arg1 l kiu d liu ca i s th nht v Arg2 l kiu d liu ca i s th hai v Result l kiu tr v ca hm c operator() Chng ta vit li lp compare, nh ngha n l mt binary_function CODE classcompare:publicbinary_function<int,int,bool> { public: booloperator()(inti,intj)const { returni==j; } }; Tng t chng ta c th t vit cc cu trc ternary_function, quaternary_function, vn vn nu mun. V d di y l mt cu trc ternary_function t vit v mt lp c nh ngha l mt ternary_function CODE template<classArg1,classArg2,classArg3,classResult> structternary_function { typedefArg1first_argument_type; typedefArg2second_argument_type; typedefArg3third_argument_type; typedefResultresult_type; }; classmultiply:publicternary_function<int,float,long,double> { public: doubleoperator()(inti,floatf,longl)const { returni*f*l; } }; Rng buc (bind) ton hng cho predicate C nhiu hm ch chp nhn mt i s, nhng chng ta li cn chuyn vo cho n cc predicate l binary predicate nh binary function hay binary functor. Trong trng hp chng ta cn rng buc ton hng cho binary predicate n tr thnh mt unary predicate V d chng ta cn dng hm find_if tm cc phn t trong mt vector tha mt binary predicate, nhng find_if li ch chp nhn unary predicate, khi chng ta cn rng buc ton hng cho binary predicate n tr thnh mt unary predicate binary predicate mun c rng buc ton hng phi c nh ngha l mt binary_function Hm bind1st Hm bind1st rng buc ton hng th nht ca mt binary predicate vi mt gi tr cho trc n tr thnh mt unary predicate

vi i s cn li ca binary predicate ban u tr thnh i s ca unary predicate kt qu CODE classcompare:publicbinary_function<int,int,bool> { public: booloperator()(inti,intj)const { returni+1==j; } }; intmain() { vector<int>v; v.push_back(4);v.push_back(0);v.push_back(1); vector<int>::iteratori=find_if(v.begin(),v.end(),bind1st(compare(),0)); if(i!=v.end())cout<<i-v.begin(); return0; } Trong v d trn, i s th nht ca compare() c rng buc bng 0, compare() tr thnh mt predicate ch c mt i s l i s cn li ca compare() ban u, v find_if ch vic truyn tham s l iterator tr n cc phn t ca v vo i s ny, qu trnh chy vng lp din ra ging nh sau compare()(0,4) //php so snh 0 + 1 == 4 tr v false compare()(0,0) //php so snh 0 + 1 == 0 tr v false compare()(0,1) //php so snh 0 + 1 == 1 tr v true Hm bind2nd Hm bind2nd rng buc ton hng th hai ca mt binary predicate vi mt gi tr cho trc n tr thnh mt unary predicate vi i s cn li ca binary predicate ban u tr thnh i s ca unary predicate kt qu CODE classcompare:publicbinary_function<int,int,bool> { public: booloperator()(inti,intj)const { returni+1==j; } }; intmain() { vector<int>v; v.push_back(4);v.push_back(0);v.push_back(1); vector<int>::iteratori=find_if(v.begin(),v.end(),bind2nd(compare(),1)); if(i!=v.end())cout<<i-v.begin(); return0; } Trong v d trn, i s th hai ca compare() c rng buc bng 1, compare() tr thnh mt predicate ch c mt i s l i s cn li ca compare() ban u, v find_if ch vic truyn tham s l iterator tr n cc phn t ca v vo i s ny, qu trnh chy vng lp din ra ging nh sau compare()(4,1) //php so snh 4 + 1 == 1 tr v false compare()(0,1) //php so snh 0 + 1 == 1 tr v true compare()(1,1) //php so snh 1 + 1 == 1 tr v false (thc ra khng c php so snh ny, hm tr v iterator ri) Mt s hm thng dng ca th vin algorithm Hm sort

CODE vector<int>v; Hm ny c 2 phin bn Sp xp li mt chui phn t theo th t tng dn (ascending) CODE sort(v.begin(),v.end()); Sp xp li mt chui phn t tha mt binary predicate CODE template<typenameT>classBigger{ public: booloperator()(constT&t1,constT&t2){returnt1>t2;} }; template<typenameT>classOutput{ public: voidoperator()(constT&t){cout<<t<<endl;} }; intmain(intargc,char*argv[]){ vector<int>v;for(inti=0;i<10;i++)v.push_back(i); sort(v.begin(),v.end(),Bigger<int>()); for_each(v.begin(),v.end(),Output<int>()); return0; } Hm transform CODE vector<int>v1; for(inti=0;i<6;i++)v1.push_back(i); Hm ny c hai phin bn: CODE intincrease(inti){return++i;} vector<int>v2; v2.resize(v1.size()); transform(v1.begin(),v1.end(),v2.begin(),increase); Phin bn th nht s ly tt c phn t t v1.begin() n v1.end(), transform chng bng hm increase, sau chp gi tr transform vo bt u t v2.begin() CODE intaddition(inti,intj){returni+j;} vector<int>v3; v3.resize(v1.size()); transform(v1.begin(),v1.end(),v2.begin(),v3.begin(),addition); Phin bn th hai s ly tt c phn t t v1.begin() n v1.end(), transform chng bng hm addition vi i s th hai l tt c phn t t v2.begin(), sau chp gi tr transform vo bt u t v3.begin() Mt s hm thng dng ca th vin functional Cc hm ton hc c bn Bao gm cng (plus) tr (minus) nhn (multiplies) chia (divides) chia ly d (modulus) i du (negate) Cc hm ny rt n gin, v d negate

CODE inta[]={1,-2,3}; transform(a,a+3,a,negate<int>()); for_each(a,a+3,Output<int>()); V d plus CODE inta[]={1,2,3,4,5}; intb[]={6,7}; intc[5]; transform(a,a+5,b,c,plus<int>()); bi trn c mt iu ng ch , bn t tm xem V d modulus CODE inta[]={1,2,3,4,5}; intb[]={2,2,2,2,2}; intc[5]; transform(a,a+5,b,c,modulus<int>()); Ci v d hm modulus ny hi k k. Modulus l mt binary function, gi s by gi chng ta mun cc phn t ca a lun modulus cho 2 th lm th no ? Phi rng buc ton hng cho modulus n tr thnh mt unary function thi. CODE inta[]={1,2,3,4,5}; intb[5]; transform(a,a+5,b,bind2nd(modulus<int>(),2)); Cc hm so snh Bao gm equal_to (==) not_equal_to (!=) greater (>) less (<) greater_equal (>=) less_equal(<=) logical_and (&&) logical_or (||) logical_not (!) Cc hm ny cch dng y nh nhau, ly mt v d hm greater CODE inta[]={3,2,5,1,4}; sort(a,a+5,greater<int>()); for_each(a,a+5,Output<int>()); Gi s ta mun dng hm count_if vi hm greater, tr v s phn t nh hn 3 chng hn. Ta lm th no ? greater l mt binary function, li phi rng buc ton hng cho n vi i s th nht l 3 ri CODE inta[]={3,2,5,1,4}; cout<<(int)count_if(a,a+5,bind1st(greater<int>(),3)); for_each(a,a+5,Output<int>());

BI 11 ASSOCIATIVE CONTAINER (CC B LU TR LIN KT) Bao gm map (nh x) multimap (a nh x) set (tp hp) multiset (a tp hp) S khc nhau gia cc associative container v sequential container mt im: -cc sequential container lu tr cc phn t (gi l cc value) v cc value ny c truy xut tun t theo v tr ca chng trong b lu tr -cc associative container lu tr cc phn t (gi l cc value) v cc kha (gi l cc key) lin kt vi cc value v cc value ny c truy xut theo cc key m chng c lin kt Map CODE #include<map> map<char*,int>nhx t mtchar*nmtint map<char*,int>mapInt; mapInt["one"]=1; cout<<mapInt["one"]; nh x t mt key n mt value. V d sau key l lp string, value l lp Person CODE classPerson{ public:stringname; Person(stringname):name(name){} friendostream&operator<<(ostream&os,constPerson&p) { os<<p.name;returnos; } }; typedefmap<string,Person>MP; typedefMP::iteratorMPI; typedefMP::const_iteratorMPCI; typedefMP::value_typeMPVT; voiddisplay(constMP&mp) { for(MPCIi=mp.begin();i!=mp.end();++i)cout<<(*i).first<<""<<(*i).second<<endl; } intmain() { MPmapPerson;Personp("Viet"); mapPerson.insert(MPVT("one",p)); display(mapPerson); return0; } Gii thch: value_type dng khi to mt cp (key,value) cho mt nh x. Cn mt cch khc l dng lp pair ca th vin utility. C 2 cch Cch mt l khi to lun mt instance ca lp pair CODE #include<utility> mapPerson.insert(pair<string,Person>("two",Person("Nam"))); Cch hai l dng hm make_pair CODE pair<string,Person>pr=make_pair(string("two"),Person("Nam"));

mapPerson.insert(pr); value_type thc cht cng l mt pair Comparator Mt functor dng so snh, sp xp, etc cc phn t trong mt map gi l mt comparator. Khi map thay v c 2 argument nh map<key K,value V> th c 3 argument l map<key K,value V,comparator C> Dng comparator so snh CODE classcomparePerson { public: booloperator()(Personp1,Personp2){ returnp1.name.compare(p2.name); } }; typedefmap<Person,int,comparePerson>MAP; MAPpMap; Personp=newPerson(...); MAP::iteratori=pMap.find(d); if(i==pMap.end())pMap.insert(MAP::value_type(d,1)); Dng comparator sp xp CODE classcomparePerson { public: booloperator()(constPerson&p1,constPerson&p2) { returnp1.name.compare(p2.name); } }; typedefmap<string,Person,comparePerson>MP; MPmapPerson;Personp("Viet"); mapPerson.insert(pair<string,Person>("one",Person("Nam"))); mapPerson.insert(pair<string,Person>("two",Person("Viet"))); mapPerson.insert(pair<string,Person>("three",Person("An"))); display(mapPerson); Bn lu l tt c cc asociative container u c xy dng sn comparator mc nh l less<key> (trong th vin functional) Ngha l khi bn khai bo CODE map<char*,int>mapInt; thc ra l CODE map<char*,int,less<char*>>mapInt; V d CODE typedefmap<char*,int>MI; typedefmap<char*,int>::iteratorMII; MIm;m["c"]=1;m["b"]=2;m["a"]=3;

for(MIIi=m.begin();i!=m.end();++i) cout<<(*i).first<<""<<(*i).second<<endl; Chy th bn s thy cc value trong map c sp xp li v tr theo cc key ca chng comparator dng vi cc sequential container CODE classPeople { public:intage; People(intage){(*this).age=age;}}; classAgeSort{ public:booloperator()(constPeople*&a,constPeople*&b) { return(*a).age>(*b).age; } }; typedeflist<constPeople*>LP; intmain() { constPeople*p1=newPeople(5);constPeople*p2=newPeople(7); LPp;p.push_back(p1);p.push_back(p2); p.sort(AgeSort());//usingsortwithcomparator for(LP::const_iteratori=p.begin();i!=p.end();++i)cout<<(**i).age; return0; } multimap Vi map th mi key ch nh x n mt v ch mt value. Vi multimap th mi key c th nh x n nhiu hn mt value, ni cch khc l nhiu value trong multimap c chung mt key CODE #include<map> typedefmultimap<string,Person>MP; MPmultimapPerson; multimapPerson.insert(MPVT("one",Person("Nam"))); multimapPerson.insert(MPVT("one",Person("Viet"))); display(multimapPerson); typedefmultimap<Person,int,comparePerson>MAP; Cng chnh v l do nhiu value trong multimap c th c chung mt key nn multi khng c operator[] nh map, tc l bn khng th gi multimapPerson[one] set set cng ging map ngoi tr mt iu, key cng chnh l value CODE #include<set> set<int>s; for(intj=0;j<6;j++)s.insert(rand()); for(set<int>::iteratori=s.begin();i!=s.end();++i)cout<<(*i)<<endl; set dng vi comparator (greater ng vai tr comparator) CODE set<int,greater<int>>s; for(intj=0;j<6;j++)s.insert(rand()); for(set<int,greater<int>>::iteratori=s.begin();i!=s.end();++i)

cout<<(*i)<<endl; set khng c operator[] multiset multiset cng ging set ngoi tr mt iu, mi key c th nh x n nhiu hn mt value, ni cch khc l nhiu value trong multiset c chung mt key Bn c th thc mc iu ny chng c ngha g, v trong set th key cng chnh l value, Khng, chng c khc y, th xem nh: CODE #include<set> set<int>s; s.insert(1); s.insert(1); for(set<int>::iteratori=s.begin();i!=s.end();++i)cout<<(*i)<<endl; multiset<int>ms; ms.insert(3); ms.insert(3); for(multiset<int>::iteratormi=ms.begin();mi!=ms.end();++mi) cout<<(*mi)<<endl;

BI 12: CC B TNG THCH V CC TH VIN KHC container adapter (cc b tng thch lu tr) Bao gm stack, queue v priority_queue Cc b tng thch lu tr, di y gi l cc b tng thch, lm cc b lu tr khc tr nn tng thch vi n bng cch ng gi (encapsulate) cc b lu tr khc tr thnh b lu tr c s ca n. V d CODE stack<int,vector<int>>s; Khi vector tr thnh b lu tr c s ca b tng thch stack Nu khng khai bo b lu tr c s, stack v queue mc nh s dng deque lm b lu tr c s, trong khi priority_queue mc nh s dng vector lm b lu tr c s, c ngha l khi khai bo CODE stack<int>s; thc ra l CODE stack<int,deque<int>>s; stack v queue stack l LIFO, queue l FIFO, xem th s khc bit qua v d palindrome sau (lu , palindrome tc l mt t c xui hay ngc u nh nhau, v d 12321, level, aka) CODE #include<stack> #include<queue> usingnamespacestd; intmain(){ stack<char>stackInt;queue<char>queueInt; chara;//storetempuserinput intn;//noofnumbersuserintendtoinput cout<<"howmanyelements:";cin>>n; for(inti=0;i<n;i++){ cin>>a; stackInt.push(a); queueInt.push(a); } for(inti=0;i<n;i++){ if(stackInt.top()!=queueInt.front()){ cout<<"notapalindrome"<<endl;break; } stackInt.pop();queueInt.pop(); if(i==n-1)cout<<"apalindrome"<<endl; } } Lu 2 c stack v queue u c cc hm sau void push(T) thm phn t vo void pop(T) g phn t ra stack c thm hm T top() truy xut phn t tip theo queue c thm hm T front() truy xut phn t tip theo T back() truy xut phn t cui cng ca queue

priority_queue priority_queue l queue trong phn t u tin lun lun l phn t ln nht theo mt tiu chun sp xp no priority_queue ging nh khi nim heap (ng) m ta bit (heap v gii thut heapsort trong mn CTDL) Thc ra priority_queue ch l queue mc nh c ci sn thm comparator less<T> ging nh cc associative container thi. Ta c th ci li comparator do ta nh ngha cho n (v d bi di y ci greater<T>) CODE #include<queue> classPlane{ intfuel; public:Plane(intfuel){(*this).fuel=fuel;} friendostream&operator<<(ostream&os,constPlane&p){ os<<p.fuel<<endl;returnos;} booloperator>(constPlane&p)const{ returnfuel>p.fuel;} }; typedefpriority_queue<Plane,vector<Plane>,greater<Plane>>PriorityQueuePlane; intmain(){ vector<Plane>vP; vP.push_back(Plane(4));vP.push_back(Plane(7)); vP.push_back(Plane(3));vP.push_back(Plane(9)); PriorityQueuePlanev(vP.begin(),vP.end()); while(!v.empty()){ cout<<v.top();v.pop(); } return0; } Lu l priority_queue c push, pop v top, khng c front v back iterator adapter (cc b tng thch con tr) Cc b tng thch iterator lm cc container v iterator khc tr nn tng thch vi n.bng cch ng gi (encapsulate) cc container v iterator khc tr thnh container v iterator c s ca n. Chng c dng khai bo c bn nh sau CODE #include<iterator> template<classContainer,classIterator> classIteratorAdapter { //nidung }; IteratorAdapter<vector<int>,vector<int>::iterator>vectorIntAdapter; Khng hc thm v iterator v iterator adapter function adapter (cc b tng thch hm) C 2 b tng thch hm chng ta hc trc l bind1st v bind2nd. Chng ta sp hc not1, not2, mem_fun, mem_fun_ref v ptr_fun. Tt c u nm trong th vin functional not1 i gi tr tr v ca mt unary predicate t false thnh true v ngc li, unary predicate phi c nh ngha l unary_function V d dng IsOdd tm cc s chn (ngha l IsOdd tr v not(true)) CODE classIsOdd:publicunary_function<int,bool>{ public:booloperator()(constint&n)const{returnn%2;} }; intmain(intargc,char*argv[]){ inta[]={1,2,3,4,5};

cout<<count_if(a,a+5,not1(IsOdd()))<<endl; return0; } not2 i gi tr tr v ca mt binary predicate t false thnh true v ngc li, binary predicate phi c nh ngha l binary_function V d dng compare so snh 2 mng vi cc phn t khng bng nhau (ngha l compare tr v not(true)) CODE classcompare:publicbinary_function<int,int,bool>{ public:booloperator()(inti,intj)const{returni==j;} }; intmain(intargc,char*argv[]){ inta[]={1,2,3,4,5}; intb[]={6,7,8,9,10}; cout<<equal(a,a+5,b,not2(compare()))<<endl; return0; } ptr_fun Chuyn mt con tr hm (function pointer) thnh mt functor CODE intaddition(inta,intb){returna+b;} intoutput(inta){cout<<a<<endl;return0;} int(*cong)(int,int)=addition; int(*xuat)(int)=output; intmain() { inta[]={1,2,3,4,5}; intb[]={6,7,8,9,10}; intc[5]; transform(a,a+5,b,c,ptr_fun(cong)); for_each(c,c+5,ptr_fun(xuat)); return0; } y chng ta c binary function l addition v unary function l output, v binary function pointer l cong v unary function pointer l xuat, v ta dng ptr_fun chuyn cc con tr hm ny thnh binary functor v unary functor ng vai tr predicate dng trong hai hm transform v for_each ptr_fun ch dng cho stand-alone v static member function, vi non-static member function phi dng mem_fun hay mem_fun_ref mem_fun Chuyn mt hm thnh vin (member function) ca mt lp thnh mt functor v truyn vo functor ny cc i s l cc con tr m tr n cc i tng ca lp CODE classPerson{ intage; public: Person(intage):age(age){} intdisplay(){cout<<age<<endl;return0;} }; intmain(){

list<Person*>l; l.push_back(newPerson(4)); l.push_back(newPerson(5)); for_each(l.begin(),l.end(),mem_fun(&Person::display)); return0; } mem_fun_ref Chuyn mt hm thnh vin (member function) ca mt lp thnh mt functor v truyn vo functor ny cc i s l cc tham chiu m tham chiu n cc i tng ca lp CODE classPerson{ intage; public: Person(intage):age(age){} intdisplay(){cout<<age<<endl;return0;} }; intmain(){ list<Person>l; l.push_back(Person(4)); l.push_back(Person(2)); l.push_back(Person(5)); for_each(l.begin(),l.end(),mem_fun_ref(&Person::display)); return0; } Mc ch chnh l tng hiu sut chng trnh, th cc k quan trng trong lp trnh game. Tng tng bn s phi gi 1 cu lnh nh th ny CODE for(list<Person*>::iteratori=l.begin();i!=l.end();i++)(**i).display(); gi ti tng hm thnh vin ca tng phn t ca list, gim hiu sut kinh khng Thay vo dng mem_fun hay mem_fun_ref, ch cn truyn vo mt con tr hay mt tham chiu ti hm thnh vin, tng hiu sut r rt.

KHUYN CO: ptr_fun v mem_fun hay mem_fun_ref, c 3 hm ny u tr li functor, c s dng rt nhiu khng ch trong lp trnh game v tng tc v hiu sut chng trnh. So snh gia cc ngn ng vi nhau, nh vo nhng c im nh con tr, etc, cng vi nhng hm tin ch c bit trong STL nht l 3 hm ny, cng t c mt mc ch th dng C++ t c tc v hiu sut hn bt k ngn ng bc cao no khc. Do bn nn hiu v s dng nhun nhuyn th vin STL, nht l 3 hm ny. y cng l phn trung tm chnh ca c mn hc C/C++ nng cao Th vin numeric Trong th vin ny c mt hm cn ch , hm accumulate CODE #include<numeric> doubleacc(doubletotal,doubleelements){ returntotal+elements; } intmain(){ multiset<double>s; for(inti=0;i<6;i++)s.insert(0.3); doublesum=accumulate(s.begin(),s.end(),0.0,ptr_fun(acc)); }

Hm accumulate truyn vo functor acc (do ptr_fun chuyn t function thnh functor) tham s l total = 0.0 v ln lt l cc phn t ca set, sau acc tnh tng total v cc element ri tr v accumulate tch ly v cui cng tr gi tr ra bin sum Th vin bitset bitset c cu trc ging nh mt mng, nhng mi phn t ch chim mt bit (nn nh kiu d liu char mi phn t chim 8 bit) V d sau ta khi to mt bitset 7 phn t vi 5 phn t u l 1,1,0,1,0 CODE #include<bitset> bitset<7>b(string("01011")); for(inti=0;i<7;i++)cout<<b[i]<<endl; Th vin valarray valarray ging nh l mt mng lu tr cc phn t. N ng ch v n c th lm vic c vi cc hm ton hc thng dng trong th vin <cmath> v cng nh nhiu php ton thng dng khc CODE #include<valarray> #include<cmath> inti=0; inta1[]={3,2,6,4,5}; valarray<int>v1(a1,5); v1<<=3;//phpton<<(dchtribit) for(i=0;i<4;i++)cout<<v1[i]<<endl; doublea2[]={2.4,6.8,0.2}; valarray<double>v2(a2,3); v2=sin(v2);//hmsin for(i=0;i<3;i++)cout<<v2[i]<<endl;

STL n y l kt thc. Mn C/C++ nng cao cn vi bi na thi l xong Nhng phn sau c ct bt, khng post gim nh chng trnh, ai thch c th t tm hiu thm: iterator, iterator adapter v allocator

BI 13: RTTI, I/O, EXTERN V PREPROCESSOR DIRECTIVE RTTI (Runtime type identification) Trong Java, bit mt object c phi l mt instance ca mt class hay khng, ta dng instanceof if(os instanceof ostream) Trong C++ ta dng hm typeid if(typeid(os)==typeid(ostream)) Trong C++, nu ta mun overload ton t xut << (output) 2 ln cng vi ostream v ofstream va c th xut ra mn hnh v tp tin trong cng mt chng trnh, chng trnh thc ra s lm vic khng thnh cng nh ta mong mun, d khng bo li g c. l v ofstream l lp con ca ostream, do ton t xut ca n b khai bo trng hp vi ton t xut ca cha n. iu ny cng tng t nh khi ta mun overload ton t nhp >> (input) 2 ln cng vi istream v ifstream, v ifstream l lp con ca istream. Khi pht trin nhng game thng mi ln nu "lt s" nhng li ngm kh pht hin nh vy th khi c "chuyn g" xy ra, vi s lng kinh hong cc lp v cc ton t c pht trin th thi gian i tm v sa li s cng rt ... kinh hong. Do , m bo an ton, khi phi overload cng mt ton t cho 2 lp cha v con, phi s dng RTTI Ta s dng RTTI bng cch dng typeid v downcast bng dynamic_cast. RTTI (Runtime type identification) (xc nh kiu d liu lc thc thi) Lc thc thi, chng trnh s xc nh kiu d liu ca object chnh xc l instance ca cha hay con. Trc ht, ta vit ring hm cho con trc. Nu xc nh l instance ca con, ta p kiu ca object xung thnh kiu ca con ri cho thc hin hm ta vit ring cho con. Nu khng phi l vn thc id: post-26368, class: nh bnh thng. Lp cha phi c hm o (istream v ostream u tha iu ny) div, hin hm ca cha postcolor V d di y ta vit 2 hm printToFile v readFromFile dnh cho con (ofstream v ifstream) trc ri dng typeid v downcast CODE #include<iostream> #include<fstream> usingnamespacestd; classPerson{ char*name; public: Person(){} Person(char*name):name(name){} voidsetName(char*name){ (*this).name=newchar[strlen(name)+1]; strcpy((*this).name,name); } char*getName()const{returnname;} voidprintToFile(ofstream&os)const{os<<*this;} voidreadFromFile(ifstream&is){is>>*this;} friendostream&operator<<(ostream&os,constPerson&p){ if(typeid(os)==typeid(ofstream)) p.printToFile(dynamic_cast<ofstream&>(os));//downcast elseos<<p.getName()<<endl; returnos; } friendofstream&operator<<(ofstream&ofs,constPerson&p){ ofs<<p.getName()<<endl; returnofs; } friendistream&operator>>(istream&is,Person&p){ if(typeid(is)==typeid(ifstream)) p.readFromFile(dynamic_cast<ifstream&>(is));//downcast else{ char*temp=newchar[20]; is.getline(temp,21); fflush(stdin); p.setName(temp); } returnis; } friendifstream&operator>>(ifstream&ifs,Person&p){ char*temp=newchar[20]; ifs>>temp; p.setName(temp); returnifs; } }; intmain(){ Persona; cin>>a; ofstreamofs("a.txt"); ofs<<a; ofs.close(); cout<<a; Personb; ifstreamifs("a.txt"); ifs>>b; ofs.open("b.txt"); ofs<<b; cout<<b; ofs.close(); return0; } I/O LIBRARY (TH VIN NHP XUT) Ta hc qua b th vin ny, ch yu ios, iostream, fstream. Ta khng i su chi tit th vin ny m ch ch thm n vi th sau y filebuf c ton b tp tin vo mt chui, s dng filebuf trong <fstream> filebuf (file buffer) b m tp tin CODE ifstreamfin;fin.open("data.dat");//m file,avostream filebuf*buf=fin.rdbuf();//ctonb streamvobuffer longsize=(*buf).pubseekoff(0,ios::end,ios::in);//kchthccabuffer (*buf).pubseekpos(0,ios::in);//v trtmkim char*temp=newchar[size];//tomngkt

(*buf).sgetn(temp,size);//chuynt buffervomngkt cout.write(temp,size);//vitmngkt volungxutramnhnh strings(temp);//chuynmngkt rachui Th vin <sstream> C 2 lp phi ch l ostringstream v istringstream Nhng i tng c a vo ostringstream vn gi nguyn kiu d liu ca n ch khng h chuyn kiu thnh string, v d CODE strings="Hithere";doubled=45.67;intn=2; ostringstreamoutput;output<<s<<d<<n; Mun xut ra nhng g a vo, ta dng istringstream CODE stringinput="Hithere45.672";strings1,s2;doubled;intn; istringstreamvalues(input);values>>s1>>s2>>d>>n; By gi ta c th xut ton b d liu trong mt file ra dng filebuf CODE filebuf*buf=fin.rdbuf(); ... strings(temp); istringstreamvalues(s);values>>s1>>s2>>s3>>...; T kha extern T kha extern thng bo vi trnh bin dch l mt phn ca chng trnh c lin kt vi mt ngn ng khc hoc c khai bo theo mt qui c khc hoc trong mt phn chng trnh khc. Trng hp th nht: ta c mt tp tin c.obj cha m nh phn ca hm dosomething vit bng C. By gi ta mun vit mt chng trnh C++ s dng th vin y. Ta khai bo trong main.cpp CODE extern"C"{ voiddosomething(inti); } intmain(intargc,char**argv){ dosomething(5); } Trng hp th hai: ta c mt th vin ha vit bng C l graphics.lib v tp tin header ca n l graphics.h. By gi ta mun vit mt chng trnh C++ s dng th vin y. Ta khai bo trong main.cpp CODE extern"C"{ #include"graphics.h" } Trng hp th ba: ta c mt d n c 2 tp tin 1.cpp v 2.cpp trong d bin a v hm in khai bo tp tin 1.cpp nh sau CODE inta=7; voidin(inta){cout<<a;} th th tp tin 2.cpp ta khai bo CODE externinta;cout<<a; externvoidin(inta);in(25); Preprocessor directive (ch th tin x l) preprocessor (b tin x l) Trc khi bin dch mt chng trnh, b bin dch (compiler) chuyn cc file m ngun qua b tin x l (preprocessor). Nhim v ca preprocessor l x l cc file m ngun qua vic x l cc ch th tin x l (preprocessor directive) cho ra cc file m ngun tng ng vi cc file m ngun ban u. Vic x l ny bao gm g b cc comment (ch thch) thi hnh cc ch th tin x l nh #include, #define hoc tng ng, vn vn v hon ton ch mc text level, do vic kim tra li rt hn ch V d --file header.h-CODE voidadd(int); #include"function.cpp" --file function.cp-CODE voidadd(inta){ return++a; } --file main.cp-CODE #include"header.h" //dungmacro #defineabs(x)((x>0)?x:-x) #definetwo2 intmain(){ add(two*abs(-5)); return0; } Sau khi qua tin x l s tr thnh mt file nh sau CODE voidadd(int); voidadd(inta){ return++a; } intmain(){

add(2*((-5>0)?-5:-(-5))); return0; } Cc ch th tin x l (preprocessor directive) #define: nh ngha mt macro (qu d ri) #include: bao gm mt tp tin hay macro vo chng trnh (qu d ri) #undef: hy b nh ngha mt macro, macro c th nh ngha li bng #define, v d CODE #definemax(a,b)((a>b)?a:b) #undefmax #definemax(a,b)((a>b)?2*a:3*b) #error: nh ngha cu thng bo khi gp li, v d CODE #errorbiloiroi intmain(){ inta=10/0; } Cu thng bo li s l cu ta nh ngha #pragma: cc ty chn ch th bin dch (ty thuc vo trnh bin dch) Cc ch th iu kin Bao gm #if (ngha l if) #elif (ngha l else if) #else (ngha l else) #endif (ngha l end if) v d on m sau CODE #ifMAX_WIDTH>10 #undefMAX_WIDTH #defineMAX_WIDTH10 #elsifMAX_WIDTH<1 #undefMAX_WIDTH #definesMAX_WIDTH1 #else #undefMAX_WIDTH #definesMAX_WIDTH5 #endif c th vit li ging nh sau CODE if(max_width>10) { #undefmax_width; max_width=10; } else { if(max_width<1) { #undefmax_width; max_width=1; } else { #undefmax_width; max_width=5; } } ngoi ra cn c #ifdef c ngha l "nu nh ngha" tng t nh n l #if defined #ifndef c ngha l "nu cha nh ngha" tng t nh n l #if !defined CODE #ifdefMYDEF_H #defineMYLIB_H #endif #ifndefMYHEADER_H #include"myheader.h" #endif Nu nh ngha MYDEF_H th nh ngha thm MYLIB_H Nu cha nh ngha MYHEADER_H th bao gm tp tin "myheader.h" vo m ngun Vit li dng defined CODE #ifdefined(MYDEF_H) #defineMYLIB_H #endif #if!defined(MYHEADER_H) #include"myheader.h" #endif Ch th #line __FILE__ l mt macro nh ngha sn, tr v ng dn ca tp tin gi macro __LINE__ l mt macro nh ngha sn, tr v th t ca dng lnh gi macro CODE #include<iostream> usingnamespacestd; intmain()

{ cout<<__FILE__<<endl; cout<<__LINE__<<endl;//dngth 6 return0; } ch th #line nh ngha li th t ca dng tip theo n CODE #include<iostream> usingnamespacestd; #line46 intmain()//dngth 46 { cout<<__FILE__<<endl; cout<<__LINE__<<endl;//dngth 46+3 return0; } ch th #line cn nh ngha li ng dn tp tin CODE #include<iostream> usingnamespacestd; #line46"c:\\main.cpp" intmain() { cout<<__FILE__<<endl;//ngdnmi cout<<__LINE__<<endl; return0; } #line v __FILE__ v __LINE__ quan trng trong vic dng debug Ch th ton t # # gi l stringizing operator directive, ch dng vi tham s ca macro N s chui ha (stringize) tham s ny n gin ch bng cch bc tham s trong cp nhy kp, v d CODE #definestr(x)cout<<#x intmain(){ str(daubung); } Ch th ton t #@ # gi l charizing operator directive, ch dng vi tham s ca macro N s k t ha (charize) tham s ny n gin ch bng cch bc tham s trong cp nhy n, v d CODE #definechr(x)#@x intmain(){ charc=chr(K); } Ch th ton t ## ## gi l merging operator directive, ch dng vi tham s ca macro N s hp (merge) tham s vi chui macro nh ngha vi n, v d CODE #definemerging(n)cout<<a##n intmain(){ inta3=1; merging(3); }

BI 14: DESTRUCTOR, CONSTRUCTOR, CONVERSION V DEBUG Hm hy o (virtual destructor) Trong v d sau, hm hy ca Derived s khng c gi CODE classBase{ public:Base(){};~Base(){};}; classDerived:publicBase{ public:Derived(){};~Derived(){};}; intmain(){ Base*b=newDerived();deleteb; } Trong trng hp ny, ta cn khai bo hm hy ca Base l hm hy o (tuyt i khng c l pure virtual destructor) CODE classBase{ public:Base(){};virtual~Base(){};}; Hm khi to chuyn kiu (conversion constructor) Bt k mt constructor mt i s no u c th tr thnh mt conversion constructor CODE classThing{ intnum; public:Thing(intnum){(*this).num=num;} friendostream&operator<<(ostream&os,constThing&t){os<<t.num;} }; voiddisplay(constThing&t){cout<<t<<endl;} intmain(){ display(7); } Hm display s kim tra lp Thing sau dng Thing(int num) lm conversion constructor gi Thing t(7);display(t); Nu chng ta mun constructor khng b dng lm conversion constructor na th ch vic thm t kha explicit vo khai bo nguyn mu ca n CODE explicitThing(intnum){....}; Th t khi to i s ca constructor constructor s ch khi to gi tr cho nhng i s ca n theo ng th t chng c khai bo trong lp, ch khng phi theo th t i s chng c khai bo trong nguyn mu hm. V d CODE classThing{ inttotal,part1,part2; Thing(inta,intb):part1(a),part2(b),total(part1+part2){} }; total s l bin dc constructor khi to gi tr trc tin (v trong lp n c khai bo trc tin) v lc ny part1 v part2 u cha c gi tr (v cha c khi to) nn php cng part1+part2 lp tc s to ra li chng trnh Hm chuyn kiu (conversion function) Hm chuyn kiu l loi hm mt lp c chc nng t ng chuyn mt object ca lp thnh mt kiu d liu -phi l hm thnh vin khng c tham s -kiu tr v khng nn l void (khng c ngha g na)

-c khai bo operator CODE classViDu{ char*s; intx,y; public: ViDu(char*s,intx,inty):s(s),x(x),y(y){} operatorchar*(){returns;} operatorint(){returnx*y;} operatorViDu(){} intoperator()(inti){returni;} }; intmain(){ ViDuv("hello",5,3); cout<<v<<endl;//vtr v char* inti=5; i+=v;//vtr v int i+=v(4);//vlfunctor cout<<i<<endl; return0; Cc k thut debug Debug l mt phn quan trng ca lp trnh game. Game pht hnh m c bug th chng ai mua, uy tn cng ty s sa st v bn s b sa thi. Cc trnh bin dch thng h tr 2 ch Debug v Release. Bi ny yu cu bn s dng mt trnh bin dch c h tr c 2 ch v bin dch cc v d vi c 2 ch Debug v Release S dng __FILE__ v __LINE__ V d gi s chng trnh di y s c bug, ta dng __FILE__ v __LINE__ in ra thng bo tp tin v dng m c li CODE intmain(){ cout<<"Bugsin"<<__FILE__<<"atline"<<__LINE__<<endl; } Ta khai bo mt macro cho vic debug. Macro ca ta ch chy di ch Debug. Nu bin dch di ch Debug, macro BUG s in ra thng bo tp tin v dng m c li, nu khng th macro BUG khng c ngha g c. Ch Debug c nh ngha sn vi macro DEBUG hoc _DEBUG ty trnh bin dch CODE #ifdefDEBUG #defineBUGcout<<"Bugsin"<<__FILE__<<"atline"<<__LINE__<<endl #endif #ifndefDEBUG #defineBUG #endif intmain() { BUG; return0; } C 2 vn au u m lp trnh vin C++ hay gp phi l null pointer v leak memory Pht hin null pointer null pointer

null pointer l mt nguy him cht ngi ta hay gp phi Con tr m tr ti mt null pointer CODE int*p=NULL; int**pp=&p;cout<<**pp; Mt cch pht hin CODE int*p=NULL; if(p!=NULL){int**pp=&p;cout<<**pp;} Tham chiu m tham chiu ti mt null pointer CODE int*p=NULL; int&r= *p;cout<<r; Mt cch pht hin CODE int*p=NULL; if(p!=NULL){int&r=*p;cout<<r;} S dng hm assert Ta debug ci li cht ngi ny bng hm assert trong th vin <cassert> void assert(int test);//nu test=0 th hm s xut li ra stderr v gi hm abort hy b chng trnh CODE #include<cassert> int*p=NULL; assert(p);//p=0nnassertfail int&r=*p;cout<<r; V bn c th dng assert trnh null pointer v d nh sau (iu g xy ra nu mt trong 2 con tr l null pointer bn cng bit ri) CODE voidswap(int*a,int*b){ assert(a); assert(b); inttemp=*a; *a=*b; *b=temp; } Pht hin leak memory leak memory (r r b nh) leak memory (r r b nh) l li xy ra khi lp trnh vin -qun hy b vng nh cp pht -cp pht vng nh bng new[] nhng hy b vng nh bng delete CODE int*p=newint[5]; deletep; -v l do no y lnh delete khng dc gi, v d chng trnh nm ra ngoi l hoc thot bt ng

CODE try{ int*a=newint[5]; cout<<a[6]<<endl; delete[]a; }catch(std::out_of_range&ex){ cerr<<ex.what(); exit(EXIT_FAILURE); } Pht hin r r b nh vi malloc v free C nhiu cch vit m pht hin r r b nh nhng ni chung u tun theo qui lut chung: nu vng nh cp pht bng new/malloc m khng gii phng bng delee/free th vng nh b r r Chng trnh sau pht hin r r b nh bng cch dng mt list lu thng tin v nhng vng nh cp pht. Nu cp pht bng hm xmalloc th lu thng tin vng nh vo trong list, nu gii phng vng nh bng xfree th xa thng tin vng nh ra khi list CODE #include<iostream> #include<list> #include<malloc.h> usingnamespacestd; structMEM_INFO { void*address; intsize; charfile[256]; intline; }; list<MEM_INFO>lmi; list<MEM_INFO>::iteratorlmii; void*xmalloc(intsize,char*file,intline) { void*ptr=malloc(size); if(ptr!=NULL) { MEM_INFOmemInfo; memset(&memInfo,0,sizeof(MEM_INFO)); memInfo.address=ptr; memInfo.size=size; strcpy(memInfo.file,file); memInfo.line=line; lmi.push_back(memInfo); } returnptr; } voidxfree(void*mem_ref) { free(mem_ref); for(lmii=lmi.begin();lmii!=lmi.end();++lmii) { if((*lmii).address==mem_ref){lmi.erase(lmii);break;} } } intmain()

{ int*a=(int*)xmalloc(2,__FILE__,__LINE__); char*b=(char*)xmalloc(4,__FILE__,__LINE__); double*c=(double*)xmalloc(8,__FILE__,__LINE__); xfree(a); xfree(c); for(lmii=lmi.begin();lmii!=lmi.end();++lmii) { MEM_INFOmemInfo=*lmii; cout<<"Address:"<<memInfo.address<<endl; cout<<"Size:"<<memInfo.size<<endl; cout<<"File:"<<memInfo.file<<endl; cout<<"Line:"<<memInfo.line<<endl; } return0; } Tng t bn c th vit cho calloc v realloc Pht hin r r b nh vi new v delete Vi vn pht hin leak memory, chng ta nn dng malloc/free vi primitive v dng new/delete vi object, v delete cn gi destructor ca object. L do na l overload ton t new v delete global scope rt phc tp v khng phi trnh bin dch no cng h tr overload hai ton t ny. Thm na nhng rng buc cht ch vi new/delete khin i khi vic ny tr nn khng th. y l mt trong nhng l do v sao malloc/free vn cn hu dng cho d c new/delete V d sau chng ta s vit mt lp, overload cc ton t new, delete, new[] v delete[] cho lp . Bn s thy l phin bn overload ca cc ton t ny c gi CODE #include<iostream> #include<malloc.h> usingnamespacestd; classMyClass { public: intdata; MyClass(){data=0;} MyClass(intdata):data(data){} void*operatornew(unsignedintsize) { void*ptr=malloc(size); cout<<"new"<<endl; returnptr; } voidoperatordelete(void*p) { cout<<"delete"<<endl; free(p); } void*operatornew[](unsignedintsize) { void*ptr=malloc(size); cout<<"new[]"<<endl; returnptr; } voidoperatordelete[](void*p) {

cout<<"delete[]"<<endl; free(p); } }; intmain() { MyClass*a=newMyClass; *a=MyClass(2); cout<<(*a).data<,endl; deletea; MyClass*b=newMyClass[5]; for(inti=0;i<5;i++)b[i]=MyClass(i); for(inti=0;i<5;i++)cout<<b[i].data; delete[]b; return0; } Cn v d di chng ta s xc nh r r b nh nu khi to bng new m khng hy b bng delete. Vi khi to bng new[] m hy b bng delete ta s gi delete [] CODE #include<iostream> #include<list> #include<malloc.h> usingnamespacestd; structMEM_INFO { void*address; intsize; charfile[256]; intline; }; list<MEM_INFO>lmi; list<MEM_INFO>::iteratorlmii; classMyClass { public: void*operatornew(unsignedintsize,char*file,intline) { void*ptr=malloc(size); if(ptr!=NULL) { MEM_INFOmemInfo; memset(&memInfo,0,sizeof(MEM_INFO)); memInfo.address=ptr; memInfo.size=size; strcpy(memInfo.file,file); memInfo.line=line; lmi.push_back(memInfo); } returnptr; } voidoperatordelete(void*p) { delete[]p;

for(lmii=lmi.begin();lmii!=lmi.end();++lmii) { if((*lmii).address==p){lmi.erase(lmii);break;} } } void*operatornew[](unsignedintsize,char*file,intline) { void*ptr=malloc(size); if(ptr!=NULL) { MEM_INFOmemInfo; memset(&memInfo,0,sizeof(MEM_INFO)); memInfo.address=ptr; memInfo.size=size; strcpy(memInfo.file,file); memInfo.line=line; lmi.push_back(memInfo); } returnptr; } voidoperatordelete[](void*p) { delete[]p; for(lmii=lmi.begin();lmii!=lmi.end();++lmii) { if((*lmii).address==p){lmi.erase(lmii);break;} } } }; intmain() { MyClass*a=new(__FILE__,__LINE__)MyClass; MyClass*b=new(__FILE__,__LINE__)MyClass[5]; for(lmii=lmi.begin();lmii!=lmi.end();++lmii) { MEM_INFOmemInfo=*lmii; cout<<"Address:"<<memInfo.address<<endl; cout<<"Size:"<<memInfo.size<<endl; cout<<"File:"<<memInfo.file<<endl; cout<<"Line:"<<memInfo.line<<endl; } return0; } Thc ra, ngay c khi bit cc k thut pht hin li vn kh ngn chn hon ton cc li trong mt d n game ln v n c pht trin bi mt i ng pht trin ng ngi lm vic lin tc vi cng cao trong mt thi gian di. S st xy ra vn l iu kh trnh khi. Lp trnh vin dnh 40% thi gian vit m 60% thi gian sa li l v th. Do k nng debug ty thuc rt nhiu vo tch ly kinh nghim thc t ch khng phi l th c th tch ly c qua mt quyn sch hay bi bo k thut no

BI 15: AUTO_PTR, MUTABLE, VOLATILE V NH GI TC CHNG TRNH auto_ptr Trong th vin <memory> c nh ngha lp auto_ptr (ngha l con tr cp pht v hy b vng nh t ng) gii quyt vn r r b nh (tuy vy vn c phin toi, do lp trnh vin t cp pht v gii phng b nh vn l la chn c khuyn khch hn) Trong v d di y, p tr n a (gi l p s hu a) Bn khng cn gi delete a Khi chng trnh kt thc, destructor ca p c gi, p s b hy, n s t ng hu lun a cho bn. l mc ch ca auto_ptr, bn khng phi lo v leak memory CODE #include<memory> classMyClass{ intdata; public: MyClass(intdata):data(data){} friendostream&operator<<(ostream&os,constMyClass&p) {os<<p.data<<endl;returnos;} }; intmain(){ MyClass*a=newMyClass(5); auto_ptr<MyClass>p(a); cout<<*p; return0; } Dng con tr bnh thng th c th gy leak memory trong v d sau CODE try{ Person*p=newPerson;(*p).func();deletep; }catch(...) Dng auto_ptr th khng lo vic y na CODE try{ auto_ptr<Person>p(newPerson);(*p).func(); }catch(...) Qu tuyt phi khng ? Khng hn th, bn thn auto_ptr cng c nhiu rc ri khc. Cng ci v d trn, ta sa li mt cht. Ln ny p s chuyn quyn s hu a cho p2. Ln ny s sinh ra li, v p2 tr n vng nh, ch khng phi p. Sau khi chuyn a cho p2 s hu, lc ny p chng s hu ci g c (kh tht, lc ny p ang tr n ci g ? ai m bit) CODE classMyClass{ intdata; public: MyClass(intdata):data(data){} friendostream&operator<<(ostream&os,constMyClass&p) {os<<p.data<<endl;returnos;} }; intmain(){ MyClass*a=newMyClass(5); auto_ptr<MyClass>p(a); cout<<*p; auto_ptr<MyClass>p2=p; cout<<*p;

return0; } const auto_ptr khng th chuyn quyn s hu c na, v d sau l khng hp l CODE MyClass*a=newMyClass(5); constauto_ptr<MyClass>p(a); auto_ptr<MyClass>p2=p; Rc ri th hai l auto_ptr khng c dng vi cu trc b nh ng, nh mng hay cc b lu tr ca STL nh vector, list CODE int*a=newint[5]; auto_ptr<int>p(a); l do l v khi destructor ca p c gi, n s gi delete a, ch khng phi delete [] a Vi cc b lu tr ca STL nh vector, list, cn l do l khi a phn t vo, cc b lu tr ny ch sao chp gi tr ca phn t gc v sau lm vic vi cc bn sao chp. Trong khi vi auto_ptr, cc bn sao chp ny l KHNG ging nhau. Do tut i khng bao gi dng (d chng thy bo li g c) CODE vector<auto_ptr<int>>v; auto_ptr c mt vi hm tin ch hm reset p tr n a ri, by gi ta tr p n b, th vng nh do a tr n s b ph hy CODE MyClass*a=newMyClass(5); cout<<*a; auto_ptr<MyClass>p(a); MyClass*b=newMyClass(7); p=newauto_ptr<MyClass>(b); cout<<*p; cout<<*a; Ta c th lm tng t nh vy bng hm reset, vng nh do a tr n cng s b ph hy CODE MyClass*a=newMyClass(5); cout<<*a; auto_ptr<MyClass>p(a); MyClass*b=newMyClass(7); p.reset(b); cout<<*p; cout<<*a; hm get Hm get tr v vng nh do auto_ptr s hu CODE Thayvcout<<*pbncth dngcout<<*(p.get()) Bn c th dng hm get kim tra xem vng nh do auto_ptr tr n c hp l hay khng Tuy vy khng th dng hm get nh sau CODE

auto_ptr<Person>p(a); auto_ptr<Person>p2(p.get()); v p vn cn quyn s hu a v p2 khng th chim ly a c hm release Hm release y nh hm get thm na l auto_ptr t b s quyn s hu vng nh Khi vn trn vi hm get c gii quyt CODE auto_ptr<Person>p(a); auto_ptr<Person>p2(p.release()); v p t b quyn s hu a nn p2 c th chim ly a mutable Trong mt s trng hp, chng ta cn mt bin s const c th thay i gi tr. V d chng ta cn thay i gi tr ca a bng hm affect CODE classMyClass{ public: inta; MyClass(inta):a(a){} intaffect()const{ returna++;//xuatraroimoithuchienphepcong } }; Trong trng hp ny const_cast l mt gii php ht sc trnh, const_cast khng m bo n b i const vi nhng object c khai bo const, do c th gy ra li khng lng c, v d CODE classMyClass{ public: inta; MyClass(inta):a(a){} intaffect()const{ MyClass*mc=const_cast<MyClass*>(this); return(*mc).a++; } }; intmain(){ constMyClassm(6); cout<<m.affect()<<endl; return0; } Trong trng hp , mutable l la chn thch hp. mutable gn ging nh "khng th l const" Mt data member ca mt const object c khai bo mutable c th thay i gi tr CODE classMyClass{ public: mutableinta; MyClass(inta):a(a){} intaffect()const{ returna++;

} }; intmain(){ MyClassm(6); cout<<m.affect()<<endl; cout<<m.a<<endl; constMyClassm2(17); cout<<m2.affect()<<endl; cout<<m2.a<<endl; return0; } volatile Khi bn lp trnh vi cc game chy a lung, mt bin c s dng bi nhiu lung khc nhau, m mi lung khng th bit c bin ny s c lung khc thay i gi tr nh th no. Mt bin nh vy phi c khai bo l volatile, tc l nhng bin m gi tr c th b thay i bt c lc no. Trong phn cng th thng dng hn chng ta. Chng ta khng hc v volatile lc ny nh gi tc chng trnh y l phn quan trng xc nh thi gian chy v nh gi tc chng trnh ca mnh c tt hay khng. Vi game th tc chy chng trnh l mt trong nhng u tin. Chng ai thch nhng game cht lng ch mc kh nhng chy chm r so vi nhng game cht lng tt hn nhng chy nhanh hn trn cng mt h thng. Bn c th tnh thi gian chy ca nhng thut ton x l ha, AI, etc bn vit trong game bng nhng hm trong th vin <ctime> y l th vin lm vic lin quan n thi gian ca C/C++ Cc hm vi time (thi im) V d sau s in ra thi im hin ti CODE #include<ctime> intmain(intargc,char**argv){ time_tcurenttime; time(&curenttime); tm*timeinfo; timeinfo=localtime(&curenttime); char*time=asctime(timeinfo); cout<<time<<endl; return0; } Gii thch: time_t: (time type) (kiu thi im) l kiu d liu lu tr thi im tnh theo giy bt u t 0 gi 0 pht 0 giy ngy 1 thng 1 nm 1970 time(): hm tr v kiu time_t thi im hin ti (current time) tm: cu trc lu thi gian, bao gm giy, pht, gi, ngy, thng, nm localtime(): hm chuyn kiu time_t v kiu tm asctime(): hm chuyn kiu tm v kiu char* Mt s hm khc ctime(): hm chuyn kiu time_t v kiu char* mktime(): hm chuyn kiu time_t v kiu tm difftime(): tnh s khc bit v thi gian theo giy gia hai time_t, tr v double V d sau dng difftime tnh s khc bit v thi gian theo giy vi do something l chng trnh ca bn CODE intmain(intargc,char**argv){ time_ttime1,time2; time(&time1);

//dosomething time(&time2); cout<<difftime(time2,time1)<<endl; return0; } Cc hm vi clock (thi khc) mt khc: mt cht thi gian, mt t xu thi gian (nh hn mt giy) khc l mt khi nim thi gian khng r rng trong ngn ng nn bn cng khng cn quan tm n mt khc bng mt phn my ca giy lm g clock_t: (clock type) (kiu thi khc) l kiu d liu lu tr thi khc clock(): tr v s lng thi khc (clock tick) qua k t khi chng trnh chy C mt macro gi l CLOCKS_PER_SEC tr v s lng khc trong mt giy (s lng khc trong mt giy ty thuc trnh bin dch v ta khng cn quan tm, mt s trnh bin dch l mt ngn, mt s l mt triu) V d sau ta s vit hm wait (ch tnh theo giy) bng cch dng clock() CODE voidwait(intseconds){ clock_twaittime; waittime=clock()+seconds*CLOCKS_PER_SEC; while(clock()<waittime); } intmain(intargc,char**argv){ time_ttime1,time2; time(&time1); wait(3);//ch 3giy time(&time2); cout<<difftime(time2,time1)<<endl; return0; } seconds*CLOCKS_PER_SEC s tnh s lng khc cn tri qua trong 3 giy v vng lp while ca bn ch cn chy trong s lng khc Ngoa ra bn cng c th tnh s khc tri qua (s khc bit v thi gian theo khc) vi do something l chng trnh ca bn CODE intmain(intargc,char**argv){ clock_tbeginclock=clock(); //dosomething clock_tendclock=clock(); cout<<endclock-beginclock<<endl; return0; } By gi bn c th dng <ctime> tnh ton thi gian chng trnh ca bn thc thi v so snh thi gian thc hin nhng thut ton ca bn, xem ci no nhanh ci no chm theo giy hoc theo khc. Cn mt gii php khc chnh xc hn l tnh ton da trn chnh tc ca CPU nhng mnh s khng trnh by v n ng n hp ng. Gii php ny tuy khng hon ton chnh xc v cn c sai s v ty theo nhiu yu t khc na nhng nh vy cng dng v sai s khng ng k. mc chp nhn c. Nhng phn sau b ct: smart pointer, garbage collector v inline assembly. Cc bn c th t tm hiu thm nu mun.

Mn lp trnh C/C++ nng cao n y kt thc.

This post has been edited by vietgameprogramming

You might also like