Class&Struct
Lậptrìnhnângcao
Kiểudữliệucócấutrúc
Class/structlàcấutrúcchophépđịnhnghĩacáckiểudữ
liệucócấutrúc:dữliệukèmtheocáchàmxửlýdữliệu
đó.Vídụ:
– Vector:VectơtronghệtoạđộĐề-các:cặptoạđộxvày,
cùngcácphéptoántổng,hiệu,\chcóhướng,\chvô
hướng…
– Circle:Hìnhtròntronghìnhhọc:toạđộtâm(x,y)vàbán
kính,cácphéptoán\nhdiện\nh,\nhchuvi,vẽ,...
– Student:Sinhviêntrongứngdụngquảnlýđàotạo:tên,
mãsinhviên,lớp,địachỉ,ngàysinh...
Bàitoánvídụ
• VectơtronghệtoạđộĐề-các:cặptoạđộxvà
y,cùngcácphéptoántổng,hiệu,\chcó
hướng,\chvôhướng…
• Viếtmộtchươngtrìnhhỗtrợ\nhtổnghai
vector,invectorramànhìnhdạng(x,y).
– add_vector():\nhvectortổngcủahaivector
– print_vector():inmộtvectorramànhình
Quánhiềuthamsố!
Cách1
Cần4thamsốcho2
vectortoánhạng
voidadd_vector(doublex1,doubley1,doublex2,doubley2,
double&x_sum,double&y_sum){
x_sum=x1+x2;y_sum=y1+y2;
}
Khôngthểreturn2biến
đạidiệnchovectortổng,
voidprint_vector(doublex,doubley){
nênphảithêm2tham
cout<<"("<
biến
}
intmain(){
doublexA=1.2,xB=2.0,yA=0.4,yB=1.6;
doublexSum,ySum;
add_vector(xA,yA,xB,yB,xSum,ySum);
print_vector(xSum,ySum);
return0;
}
Đọccodekhómàhiểuđâylàcácvector
structVector{
doublex;
doubley;
...
};
Vectoradd(Vectorv1,Vectorv2){
Vectorsum;
Ítthamsố,dễđọc.Dodữ
sum.x=v1.x+v2.x;
liệuvectorđượcđónggói
sum.y=v1.y+v2.y;
trongmộtcấutrúc
returnsum;
}
voidprint(Vectorv){
cout<<"("<
}
intmain(){
Vectora(1.2,0.4),b(2.0,1.6);
Vectorsum=add(a,b);
Codegọn,
print(sum);
dễhiểuđâylàcácvector
return0;
}
Cáchtốthơn
Cáchtốthơnnữa
structVector{
doublex;
doubley;
Vectoradd(Vectorother){...}
voidprint(){...}
};
intmain(){
Vectora(1.2,0.4),b(2.0,1.6);
Vectorsum=a.add(b);
sum.print();
return0;
}
Cáchàmxửlídữliệu
cũngđượcđónggói
kèmvớidữliệu
STRUCTVÀCÁCBIẾNTHÀNHVIÊN
Địnhnghĩakiểudữliệumới
structVector{địnhnghĩakiểuVectorgồm:
doublex;
-trườngdữliệux
doubley;
-trườngdữliệuy
};
Ýnghĩa:
v1
x y
v2
x y
Vectorv1,v2;
biếnv1,v2thuộckiểuVector
MỗibiếnthuộckiểuVectorcóhaithànhviêndữliệulàx
kiểudoublevàykiểudouble.
Sửdụng
structVector{địnhnghĩakiểuVectorgồm:
doublex;
-trườngdữliệux
doubley;
-trườngdữliệuy
};
Vectorv;
v.x=1.0;
v.y=2.1;
cout<
khaibáobiếnvkiểuVector
gángiátrịchotrườngxcủabiếnv
gángiátrịchotrườngycủabiếnv
lấygiátrịcủaxcủay.
Vídụ
structPerson{địnhnghĩakiểudữliệuPersongồm:
stringname;
-trườngdữliệuname
stringaddress;
-trườngdữliệuaddress
intage;
-trườngdữliệuage
};
sửdụng
Personjohn;
khaibáobiếnjohnkiểuPerson
john.name=“John”;
john.address=“London”;
john.age=20;
Point–tọađộtrongkhônggian2D
structPoint{
doublex;
doubley;
Point(int_x,int_y){…}
};
Triangle–tamgiác
structTriangle{
Pointa;
Pointb;
Pointc;
Triangle(intx1,inty1,intx2,inty2,
intx3,inty3)
:a(x1,y1),b(x2,y2),c(x3,y3)
{}
Gọiconstructor
Point(intx,inty)để
};
structTriangle{
Pointa[3];
};
hoặc
Gọiconstructor
Point()đểkhởitạoa,
b,c
khởitạoa,b,c
Khởitạocácbiếnthànhviên
structTriangle{
Pointa;
Pointb;
Pointc;
Triangle(intx1,inty1,intx2,inty2,
intx3,inty3)
:a(x1,y1),b(x2,y2),c(x3,y3)
{}
Gọiconstructor
Point(intx,inty)để
khởitạoa,b,c
Triangle()
{}
};
Gọingầmconstructormặcđịnh
Point()đểkhởitạoa,b,c
Khởitạobiếnthànhviên
structTriangle{
Pointa;
Pointb;
Pointc;
};
structTriangle{
Pointa[3];
};
Khôngkhaibáoconstructor
Sẽcóconstructormặcđịnh
Triangle()
–khôngthamsố,nộidungrỗng
–Vớinhiệmvụngầmgọi
constructormặcđịnhPoint()để
khởitạoa,b,c
Hoặca[0],a[1],a[2].
structlàmthamsốchohàm
• Truyềnbằnggiátrị-passbyvalue
voidprint(Vectorv){
cout<<"("<
}
• Truyềnbằngthamchiếu-passbyreference
voidprint(Vector&v){
cout<<"("<
}
structlàmthamsốchohàm
• Truyềnbằngcontrỏ-passbypointer
voidprint(Vector*pv){
cout<<"("<<pv->x<<","<<pv->y<<")";
}
Chúý,khitruynhậpcáctrườngtừcontrỏ,phải
dùngtoántửmũitên(->)thayvìdấuchấm(.)
Structvàcontrỏ
structVector{
doublex;
doubley;
};
Vector*
pV->x =
(*pV).y
cout <<
Vectorv;
v.x=1.0;
v.y=2.1;
cout<
pV = &v;
contrỏtớiv
1.0;
truynhậpv.xtừcontrỏ
= 2.1;
truynhậpv.ytừbiếnv
pV->x << “,” << (*pV).y;
Cúpháptruynhậpcáctrường
structVector{
doublex;
Vector v;
doubley;
Vector* pV = &v;
};
Dùngdấuchấm(.)đểtruynhậptừbiến/ônhớstruct:
v.x
(*pv).x
Dùngmũitên(->)đểtruynhậpbằngcontrỏ/địachỉ:
pv->x
(&v)->x
Cấpphátbộnhớđộng
• Giốnghệtđốivớicáckiểudữliệukhác
int*p=newint;
//sửdụngp…
deletep;
Vector*p=newVector;
//sửdụngp…
deletep;
int*arr=newint[10];
//sửdụngarr…
delete[]arr;
Vector*arr=newVector[10];
//sửdụngarr…
delete[]arr;
Structvàphépgán
• Giốngnhưcáckiểudữliệuthôngthường,
phépgánđượcthựchiệnkhi:
– Phépgán
Vector v1 = v2;
– Truyềnthamtrịvàohàm
void print(Vector v) {…}
print(v1); //v1đượcgánchothamsốv
– Trảvềgiátrị
return v1; //v1đượcgánchobiếnnhậngiátrịtrảvề
• Phépgánlàmgì?copytừngtrườngvàobiếnđích–
copynông,chỉsaochépgiátrị.
Copynông–swallowcopy
s=s1;
s
s1
‘a’
‘a’
10
10
0x18a4
0x18a4
Copynông–swallowcopy
s=s1;
s
s1
‘a’
‘a’
10
10
0x18a4
0x18a4
0x18a4
‘abcd’
Đốivớicontrỏ,copynôngcónghĩachỉsaochépcontrỏ,
khôngsaochépnộidungnótrỏtới
Bestprac™ce
• Khimuốntruyềnstructvàohàmởdạngchỉ
đọc,nêntruyềnhằngthamchiếuthayvìtham
trị
– Khôngtốncôngcopy
– Vẫnđảmbảohàmkhôngsửađốisố.
voidprint(constVector&v){...}
cóhiệuứngtươngđươngnhưngtốthơn
voidprint(Vectorv){...}
HÀMTHÀNHVIÊN
structVector{
Hàmxửlýnằmngoài
doublex;
doubley;
};
voidprint(constVector&v){
cout<<"("<
}
Vectoradd(constVector&v1,constVector&v2){
Vectorsum;
sum.x=v1.x+v2.x;
sum.y=v1.y+v2.y;
returnsum;
}