Professional Documents
Culture Documents
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));
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
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;
}
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;
}
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;
}
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;
}
}
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;
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;
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*)
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
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>());
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;
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;
(*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);
}
-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
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
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.