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;
}
div, id: post-25916, class: postcolor
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
hin
hm caclass:
cha nh
bnh thng. Lp cha phi c hm o (istream v ostream u tha iu ny)
div, id:
post-26368,
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