Tải bản đầy đủ (.pdf) (33 trang)

Giáo trình C++ - Đại Học Bách Khoa (phần 8) potx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.45 MB, 33 trang )

-233-
Ch
Ch
Ch
Ch
ơ
ơ
ơ
ơ
ng
ng
ng
ng
6
6
6
6
khu
khu
khu
khu
ô
ô
ô
ô
n
n
n
n
h
h


h
h
ì
ì
ì
ì
nh
nh
nh
nh
(Template)
(Template)
(Template)
(Template)
Mụcđíchchơngnày:
1.
Hiểuđợclợiíchcủaviệcsửdụngkhuônhìnhhàmvàkhuônhìnhlớpđể
viếtchơngtrình.
2.Biếtcáchtạovàsửdụngmộtkhuônhìnhhàmvàkhuônhìnhlớp.
3.Kháiniệmcácthamsốkiểuvàcácthamsốbiểuthứctrongkhuônhình
hàm,khuônhìnhlớp.
4.
Địnhnghĩachồngkhuônhìnhhàm.
5.Cụthểhoámộtkhuônhìnhhàm,mộthàmthànhphầncủakhuônhìnhlớp.
6.Thuậttoánsảnsinhmộtthểhiệnhàm(hàmthểhiện)củamộtkhuônhình
hàm
7.
Cácvấnđềkháccủalậptrìnhhớngđốitợngliênquanđếnkhuônhình
lớp.
Khu

Khu
Khu
Khu
ô
ô
ô
ô
n
n
n
n
h
h
h
h
ì
ì
ì
ì
nh
nh
nh
nh
h
h
h
h
à
à
à

à
m
m
m
m
Khu
Khu
Khu
Khu
ô
ô
ô
ô
n
n
n
n
h
h
h
h
ì
ì
ì
ì
nh
nh
nh
nh
h

h
h
h
à
à
à
à
m
m
m
m
l
l
l
l
à
à
à
à
g
g
g
g
ì
ì
ì
ì
?
?
?

?
Tađãbiếtđịnhnghĩachồnghàmchophépdùngmộttênduynhấtchonhiều
hàmthựchiệncáccôngviệckhácnhau.Kháiniệmkhuônhìnhhàmcũngchophép
sửdụngcùngmộttênduynhấtđểthựchiệncáccôngviệckhácnhau,tuynhiênso
vớiđịnhnghĩachồnghàm,nócóphầnmạnhhơnvàchặtchẽhơn;mạnhhơnvìchỉ
cầnviếtđịnhnghĩakhuônhìnhhàmmộtlần,rồisauđóchơngtrìnhbiêndịchlàm
chonóthíchứngvớicáckiểudữliệukhácnhau;chặtchẽhơnbởivìdựatheo
khuônhìnhhàm,tấtcảcáchàmthểhiệnđợcsinhrabởitrìnhbiêndịchsẽtơng
ứngvớicùngmộtđịnhnghĩavànhvậysẽcócùngmộtgiảithuật.
T
T
T
T




o
o
o
o
m
m
m
m




t

t
t
t
khu
khu
khu
khu
ô
ô
ô
ô
n
n
n
n
h
h
h
h
ì
ì
ì
ì
nh
nh
nh
nh
h
h
h

h
à
à
à
à
m
m
m
m
Giảthiếtrằngchúngtacầnviếtmộthàm
m in
đaragiátrịnhỏnhấttronghai
giátrịcócùngkiểu.Tacóthểviếtmộtđịnhnghĩanhthếđốivớikiểu
int
nhsau:
intmin(int
a,
int
b)
{
if(a
<
b)
return
a;
Khuônh
ì
nh
-234-
elsereturn

b;
}
Giảsử,talạiphảiviếtđịnhnghĩahàm
min()
chokiểu
double
double
double
double
,
float
float
float
float
,
char,char
char,char
char,char
char,char
*
float
min(float
a,
float
b){
if(a<b)
return
a;
else
b;}

Nếutiếptụcnhvậy,sẽcókhuynhhớngphảiviếtrấtnhiềuđịnhnghĩahàm
hoàntoàntơngtựnhau;chỉcókiểudữliệucácthamsốlàthayđổi.Cácchơng
trìnhbiêndịchC++hiệncóchophépgiảiquyếtđơngiảnvấnđềtrênbằngcách
địnhnghĩamộtkhuônhìnhhàmduynhấttheocáchnhsau:
#include
<iostream.h>
//tạomộtkhuônhìnhhàm
template
<class
T>
T
min(T
a,
T
b)
{
if(a
<
b)
return
a;
elsereturn
b;
}
Sosánhvớiđịnhnghĩahàmthôngthờng,tathấychỉcódòngđầutiênbịthay
đổi:
template
<class
T>T
min

(Ta,Tb)
trong
đó
template<class
T>
xácđịnhrằngđólàmộtkhuônhìnhvớimộtthamsốkiểuT;
Phầncònlại
T
min(T
a,Tb)
nóirằng,
m in()
làmộthàmvớihaithamsốhìnhthứckiểu
T
vàcógiátrịtrảvề
cũnglàkiểu
T
.
Khuônh
ì
nh
-235-
S
S
S
S





d
d
d
d




ng
ng
ng
ng
khu
khu
khu
khu
ô
ô
ô
ô
n
n
n
n
h
h
h
h
ì
ì

ì
ì
nh
nh
nh
nh
h
h
h
h
à
à
à
à
m
m
m
m
Khu
Khu
Khu
Khu
ô
ô
ô
ô
n
n
n
n

h
h
h
h
ì
ì
ì
ì
nh
nh
nh
nh
h
h
h
h
à
à
à
à
m
m
m
m
cho
cho
cho
cho
ki
ki

ki
ki




u
u
u
u
d
d
d
d




li
li
li
li




u
u
u
u

c
c
c
c
ơ
ơ
ơ
ơ
s
s
s
s




Đểsửdụngkhuônhìnhhàm
min()
vừatạora,chỉcầnsửdụnghàm
min()
trongnhữngđiềukiệnphùhợp(ởđâycónghĩalàhaithamsốcủahàmcócùng
kiểudữliệu).Nhvậy,nếutrongmộtchơngtrìnhcóhaithamsốnguyên
n

p
,
vớilờigọi
min(n,p)
chơngtrìnhbiêndịchsẽtựđộngsảnsinhrahàm
min()

(ta
gọilàmộthàmthểhiện)tơngứngvớihaithamsốkiểunguyên
int
int
int
int
.Nếuchúngta
gọi
min()
vớihaithamsốkiểu
float
float
float
float
,chơngtrìnhbiêndịchcũngsẽtựđộngsản
sinhmộthàmthểhiện
min
kháctơngứngvớicácthamsốkiểu
float
float
float
float
vàcứthế.
Sauđâylàmộtvídụhoànchỉnh:
V
V
V
V
í
í

í
í
d
d
d
d




6.1
6.1
6.1
6.1
/*template1.cpp*/
/*template1.cpp*/
/*template1.cpp*/
/*template1.cpp*/
#include
<iostream.h>
#include<conio.h>
//tạomộtkhuônhìnhhàm
template
<class
T>
T
min(T
a,
T
b)

{
if
(a<
b)
return
a;
elsereturn
b;
}
//vídụsửdụngkhuônh
ì
nhhàmmin
voidmain()
{
clrscr();
int
n=
4,
p=
12;
float
x=
2.5,
y=
3.25;
cout<<"min
(n,
p)
=
"<<min(n,

p)<<"\n";
//intmin(int,int)
cout<<"min
(x,
y)
=
"<<min(x,
y)<<"\n";
//floatmin(float,float)
getch();
}
min(n,p)=4
min(x,y)=2.5
Khuônh
ì
nh
-236-
Khu
Khu
Khu
Khu
ô
ô
ô
ô
n
n
n
n
h

h
h
h
ì
ì
ì
ì
nh
nh
nh
nh
h
h
h
h
à
à
à
à
m
m
m
m
min
min
min
min
cho
cho
cho

cho
ki
ki
ki
ki




u
u
u
u
char
char
char
char
*
*
*
*
/*template2.cpp*/
/*template2.cpp*/
/*template2.cpp*/
/*template2.cpp*/
#include
<iostream.h>
#include<conio.h>
template
<class

T>
T
min
(Ta,
T
b)
{
if(a
<
b)
return
a;
elsereturn
b;
}
voidmain()
{
clrscr();
char
*
adr1
=
"DHBK";
char
*
adr2
=
"CDSD";
cout
<<

"min(adr1,adr2)="<<min(adr1,adr2);
getch();
}
min(adr1,adr2)=DHBK
Kếtquảkháthúvịvìtahyvọnghàm
m in()
trảvềxâu"CDSD".Thựctế,với
biểuthức
min(adr1,
adr2)
,chơngtrìnhbiêndịchđãsinhrahàmthểhiệnsau
đây:
char
*
min(char
*
a,
char
*
b)
{
if(a
<
b)
return
a;
elsereturn
b;
}
Việcsosánh

a<b
thựchiệntrêncácgiátrịbiếntrỏ(ởđâytrongcáckhuôn
hìnhmáyPCtaluônluôncó
a<b
).Ngợclạiviệchiểnthịthựchiệnbởitoántử
<<sẽđaraxâukýtựtrỏbởicontrỏkýtự.
K
K
K
K
hu
hu
hu
hu
ô
ô
ô
ô
n
n
n
n
h
h
h
h
ì
ì
ì
ì

nh
nh
nh
nh
h
h
h
h
à
à
à
à
m
m
m
m
min
min
min
min
v
v
v
v




i
i

i
i
ki
ki
ki
ki




u
u
u
u
d
d
d
d




li
li
li
li





u
u
u
u
l
l
l
l




p
p
p
p
Đểápdụngkhuônhìnhhàm
min()
ởtrênvớikiểulớp,cầnphảiđịnhnghĩalớp
saochocóthểápdụngphéptoánsosánh

<

vớicácđốitợngcủalớpnày,nghĩa
làtaphảiđịnhnghĩamộthàmtoántử
operator
<
cholớp.Sauđâylàmộtvídụ
minhhoạ:
Khuônh

ì
nh
-237-
V
V
V
V
í
í
í
í
d
d
d
d




6.2
6.2
6.2
6.2
/*template3.cpp*/
/*template3.cpp*/
/*template3.cpp*/
/*template3.cpp*/
#include
<iostream.h>
#include<conio.h>

//khuônhìnhhàmmin
template
<class
T>
T
min(
T
a,
T
b)
{
if(a
<
b)
return
a;
elsereturn
b;
}
//lớpvect
classvect
{
int
x,y;
public:
vect(int
abs=0,intord
=
0)
{

x=
abs,
y=
ord;}
void
display()
{
cout<<x<<"
"<<y<<"\n";
}
friendint
operator
<
(vect
,
vect);
};
int
operator
<
(vect
a,
vect
b)
{
returna.x*a.x
+
a.y*a.y
<
b.x*b.x

+
b.y*b.y;
}
voidmain()
{
clrscr();
vect
u(3,2),v(4,1);
cout<<"min
(u,
v)
=
";
min(u,v).display();
getch();
}
min(u,v)=32
Nếutaápdụngkhuônhìnhhàm
min()
đốivớimộtlớpmàchađịnhnghĩa
toántử<,chơngtrìnhbiêndịchsẽđaramộtthôngbáolỗitơngtựnhviệc
địnhnghĩamộthàm
min()
chokiểulớpđó.
Khuônh
ì
nh
-238-
C
C

C
C
á
á
á
á
c
c
c
c
tham
tham
tham
tham
s
s
s
s




ki
ki
ki
ki





u
u
u
u
c
c
c
c




a
a
a
a
khu
khu
khu
khu
ô
ô
ô
ô
n
n
n
n
h
h

h
h
ì
ì
ì
ì
nh
nh
nh
nh
h
h
h
h
à
à
à
à
m
m
m
m
Phầnnàytrìnhbàycáchđavàocácthamsốkiểutrongmộtkhuônhìnhhàm,
đểchơngtrìnhbiêndịchsảnsinhmộthàmthểhiện.
C
C
C
C
á
á

á
á
c
c
c
c
tham
tham
tham
tham
s
s
s
s




ki
ki
ki
ki




u
u
u
u

trong
trong
trong
trong
đị
đị
đị
đị
nh
nh
nh
nh
ngh
ngh
ngh
ngh
ĩ
ĩ
ĩ
ĩ
a
a
a
a
khu
khu
khu
khu
ô
ô

ô
ô
n
n
n
n
h
h
h
h
ì
ì
ì
ì
nh
nh
nh
nh
h
h
h
h
à
à
à
à
m
m
m
m

Mộtcáchtổngquát,khuônhìnhhàmcóthểcómộthaynhiềuthamsốkiểu,
vớimỗithamsốnàycótừkhoáclass
class
class
class
điliềntrớc,chẳnghạnnh:
template
<class
T,
class
U>
intfct
(Ta,T
*b,
Uc)
{
}
Cácthamsốnàycóthểđểởbấtkỳđâutrongđịnhnghĩacủakhuônhìnhhàm,
nghĩalà:
Trongdòngtiêuđề(nhđãchỉratrongvídụtrên).
Trongcáckhaibáocácbiếncụcbộ.
(i)
Trongcácchỉthịthựchiện.
Chẳnghạn:
template
<class
T,
class
U>
intfct

(Ta,
T
*b,
U
c)
{
T
x;
//biếncụcbộxkiểuT
U
*adr;
//biếncụcbộadrkiểuU*

adr
=
new
T
[10];
//cấpphá
t
mộtmảng10thànhphầnkiểuT n=sizeof(T);
}
Taxemchơngtrìnhsau:
V
V
V
V
í
í
í

í
d
d
d
d




6.3
6.3
6.3
6.3
/*templat4.cpp*/
/*templat4.cpp*/
/*templat4.cpp*/
/*templat4.cpp*/
#include
<iostream.h>
#include<conio.h>
template
<class
T,
class
U>
T
fct(T
x,
U
y,

T
z)
{
return
x+y+
z;
}
voidmain()
{
clrscr();
int
n=1,
p=
2,
q=
3;
Khuônh
ì
nh
-239-
float
x
=2.5,
y=
5.0;
cout<<fct(
n,x,
p)<<"\n";
//(int)5
cout

<<fct(x,
n,
y)<<"\n";
//(float)8.5
cout
<<fct(n,
p,
q)<<"\n";
//(int)6
//cout<<fct(n,p,x)<<"\n";//lỗ
i
getch();
}
Trongmọitrờnghợp,mỗithamsốkiểuphảixuấthiệnítnhấtmộtlầntrong
khaibáodanhsáchcácthamsốhìnhthứccủakhuônhìnhhàm.Điềuđóhoàntoàn
logicbờivìnhờcácthamsốnày,chơngtrìnhdịchmớicóthểsảnsinhrahàmthể
hiệncầnthiết.Điềugìsẽxảyranếutrongdanhsáchcácthamsốcủakhuônhình
hàmkhôngcóđủcácthamsốkiểu?Hiểnnhiênkhiđóchơngtrìnhdịchkhôngthể
xácđịnhcácthamsốkiểudữliệuthựcứngvớicácthamsốkiểuhìnhthứctrong
template< >
.
Khuônhìnhhàmsauđâythựchiệntraođổinộidungcủahaibiến.
V
V
V
V
í
í
í
í

d
d
d
d




6.4
6.4
6.4
6.4
/*templat5.cpp*/
/*templat5.cpp*/
/*templat5.cpp*/
/*templat5.cpp*/
#include
<iostream.h>
#include<conio.h>
//địnhnghĩakhuônh
ì
nhhàmđổichỗnộidunghaibiếnvớikiểubấtkỳ
template
<class
X>
voidswap(X&a,
X
&b)
{
X

temp;
temp=a;
a=b;
b=temp;
}
voidmain()
{
clrscr();
inti=10,j=20;
floatx=10.1,y=23.1;
cout<<"I
J
bandau:"<<i<<"
"<<j<<endl;
cout<<"X
Y
bandau:"<<x<<"
"<<y<<endl;
swap(i,j);
//đổ
i
chỗhaisốnguyên
Khuônh
ì
nh
-240-
swap(x,y);
//đổ
i
chỗhaisốnguyên

cout<<"I
J
saukhidoicho:"<<i<<"
"<<j<<endl;
cout<<"X
Y
saukhidoicho:"<<x<<"
"<<y<<endl;
getch();
}
IJbandau:1020
XYbandau:10.123.1
IJsaukhidoicho:2010
XYsaukhidoicho:23.110.1
Gi
Gi
Gi
Gi




i
i
i
i
thu
thu
thu
thu





t
t
t
t
s
s
s
s




n
n
n
n
sinh
sinh
sinh
sinh
m
m
m
m





t
t
t
t
h
h
h
h
à
à
à
à
m
m
m
m
th
th
th
th




hi
hi
hi
hi





n
n
n
n
Trởlạikhuônhìnhhàm
m in()
:
template
<class
T>
T
min(T
a,
T
b)
{
if(a
<
b)
return
a;
elsereturn
b;
}
Vớicáckhaibáo:
int

n;
char
c;
câuhỏiđặtralà:chơngtrìnhdịchsẽlàmgìkhigặplờigọikiểunhlà
min(n,c)
?Câutrảlờidựatrênhainguyêntắcsauđây:
(ii)
C++quyđịnhphảicómộtsựtơngứngchínhxácgiữakiểucủathamsố
hìnhthứcvàkiểuthamsốthựcsựđợctruyềnchohàm,tắclàtachỉcóthểsử
dụngkhuônhìnhhàm
min()
trongcáclờigọivớihaithamsốcócùngkiểu.
Lờigọi
min(n,
c)
khôngđợcchấpnhậnvàsẽgâyralỗibiêndịch.
(iii)
C++thậmchícònkhôngchophépcácchuyểnkiểuthôngthờngnhlà:
T
thànhconst
T
hay
T[]
thành
T*
,nhữngtrờnghợphoàntoànđợcphéptrong
địnhnghĩachồnghàm.
Tathamkhảođoạnchơngtrìnhsauđây:
int
n;

char
c;
unsigned
int
q;
Khuônh
ì
nh
-241-
constint
r=
10;
intt[10];
int*adi;

min(n,
c)
//lỗi
min(n,
q)
//lỗi
min(n,
r)
//lỗi
min(t,adi)
//lỗi
Kh
Kh
Kh
Kh





i
i
i
i
t
t
t
t




o
o
o
o
c
c
c
c
á
á
á
á
c
c

c
c
bi
bi
bi
bi
ế
ế
ế
ế
n
n
n
n
c
c
c
c
ó
ó
ó
ó
ki
ki
ki
ki





u
u
u
u
d
d
d
d




li
li
li
li




u
u
u
u
chu
chu
chu
chu





n
n
n
n
Trongkhuônhìnhhàm,thamsốkiểucóthểtơngứngkhithìmộtkiểudữliệu
chuẩn,khithìmộtkiểudữliệulớp.Sẽlàmgìkhitacầnphảikhaibáobêntrong
khuônhìnhhàmmộtđốitợngvàtruyềnmộthaynhiềuthamsốchohàmthiếtlập
củalớp.Xemvídụsauđây:
template
<class
T>
fct(T
a)
{
T
x(3);
//x
l
àmộtđối
t
ợngcụcbộkiểuTmàchúngtaxâydựngbằngcách
//truyềngiátr

3chohàmthiếtlập
}
Khisửdụnghàm
fct()
chomộtkiểudữliệulớp,mọiviệcđềutốtđẹp.Ngợc

lại,nếuchúngtacốgắngápdụngchomộtkiểudữliệuchuẩn,chẳnghạnnhint
int
int
int
,
khiđóchơngtrìnhdịchsảnsinhrahàmsauđây:
fct(int
a)
{
intx(3);
}
Đểchochỉthị
intx(3)
;
khônggâyralỗi,C++đãngầmhiểucâulệnhđónhlàphépkhởitạobiếnx
vớigiátrị3,nghĩalà:
int
x=3;
Mộtcáchtơngtự:
doublex(3.5);
//thayvìdoublex=3.5;
charc('e');
//thayvìcharc='e';
Khuônh
ì
nh
-242-
C
C
C

C
á
á
á
á
c
c
c
c
h
h
h
h




n
n
n
n
ch
ch
ch
ch
ế
ế
ế
ế
c

c
c
c




a
a
a
a
khu
khu
khu
khu
ô
ô
ô
ô
n
n
n
n
h
h
h
h
ì
ì
ì

ì
nh
nh
nh
nh
h
h
h
h
à
à
à
à
m
m
m
m
Vềnguyêntắc,khiđịnhnghĩamộtkhuônhìnhhàm,mộtthamsốkiểucóthể
tơngứngvớibấtkỳkiểudữliệunào,chodùđólàmộtkiểuchuẩnhaymộtkiểu
lớpdongờidùngđịnhnghĩa.Dovậykhôngthểhạnchếviệcthểhiệnđốivớimột
sốkiểudữliệucụthểnàođó.Chẳnghạn,nếumộtkhuônhìnhhàmcódòngđầu
tiên:
template
<class
T>
voidfct(T)
chúngtacóthểgọi
fct()
vớimộtthamsốvớikiểubấtkỳ:int
int

int
int
,
float
float
float
float
,
int
int
int
int
* ,
int
int
int
int
**,
t
*
(
t
làmộtkiểudữliệunàođấy)
Tuynhiên,chínhđịnhnghĩabêntrongkhuônhìnhhàmlạichứamộtsốyếutố
cóthểlàmchoviệcsảnsinhhàmthểhiệnkhôngđúngnhmongmuốn.Tagọiđó
làcáchạnchếcủacáckhuônhìnhhàm.
Đầutiên,chúngtacóthểchorằngmộtthamsốkiểucóthểtơngứngvớimột
contrỏ.Dođó,vớidòngtiêuđề:
template
<class

T>
voidfct(T
*)
tachỉcóthểgọi
fct()
vớimộtcontrỏđếnmộtkiểunàođó:int
int
int
int
*,
int
int
int
int
**,
t
*,t**
.
Trongcáctrờnghợpkhác,sẽgâyracáclỗibiêndịch.Ngoàira,trongđịnh
nghĩacủamộtkhuônhìnhhàm,cóthểcócácchỉthịkhôngthíchhợpđốivớimột
sốkiểudữliệunhấtđịnh.Chẳnghạn,khuônhìnhhàm:
template
<class
T>
T
min(T
a,
T
b)
{

if(a
<
b)
return
a;
elsereturn
b;
}
khôngthểdùngđợcnếu
T
tơngứngvớimộtkiểulớptrongđóphéptoán<
khôngđợcđịnhnghĩachồng.Mộtcáchtơngtựvớimộtkhuônhìnhhàmkiểu:
template
<class
T>
voidfct(T)
{

T
x(2,5);
/*đốitợngcụcbộđợckhở
i
tạobằngmộthàmthiếtlậpvới
haithamsố*/
}
khôngthểápdụngchocáckiểudữliệulớpkhôngcóhàmthiếtlậpvớihai
thamsố.
Tómlại,mặcdùkhôngtồntạimộtcơchếhìnhthứcđểhạnchếkhảnăngáp
dụngcủacáckhuônhìnhhàm,nhngbêntrongmỗimộtkhuônhìnhhàmđềucó
Khuônh

ì
nh
-243-
chứanhữngnhântốđểngờitacóthểbiếtđợckhuônhìnhhàmđócóthểđợcáp
dụngđếnmứcnào.
C
C
C
C
á
á
á
á
c
c
c
c
tham
tham
tham
tham
s
s
s
s




bi

bi
bi
bi




u
u
u
u
th
th
th
th




c
c
c
c
c
c
c
c





a
a
a
a
m
m
m
m




t
t
t
t
khu
khu
khu
khu
ô
ô
ô
ô
n
n
n
n
h

h
h
h
ì
ì
ì
ì
nh
nh
nh
nh
h
h
h
h
à
à
à
à
m
m
m
m
Trongđịnhnghĩacủamộtkhuônhìnhhàmcóthểkhaibáocácthamsốhình
thứcvớikiểuxácđịnh.Tagọichúnglàcácthamsốbiểuthức.Chơngtrình
templat6.cpp
sauđâyđịnhnghĩamộtkhuônhìnhhàmchophépđếmsốlợng
cácphầntửnul(0đốivớicácgiátrịsốhoặcNULLnếulàcontrỏ)trongmộtbảng
vớikiểubấtkỳvàkíchthớcnàođó:
V

V
V
V
í
í
í
í
d
d
d
d




6.5
6.5
6.5
6.5
/*templat6.cpp*/
/*templat6.cpp*/
/*templat6.cpp*/
/*templat6.cpp*/
#include
<iostream.h>
#include<conio.h>
template
<class
T>
int

compte(T
*
tab,int
n)
{
int
i,nz
=
0;
for(i=0;i<n;i++)
if
(!tab[i])
nz++;
returnnz;
}
voidmain()
{
clrscr();
intt[5]
=
{5,
2,0,2,
0};
charc[6]
={
0,
12,
0,0,
0};
cout<<"compte(t)

=
"<<compte(t,
5)<<"\n";
cout<<"compte(c)
=
"<<compte(c,6)<<"\n";
getch();
}
compte(t)=2
compte(c)=4
Tacóthểnóirằngkhuônhìnhhàm
compte
địnhnghĩamộthọcáchàm
compte
trongđókiểucủathamsốđầutiênlàtuỳý(đợcxácđịnhbởilờigọi),còn
kiểucủathamsốthứhaiđãxácđịnh(kiểu
int
int
int
int
).
Khuônh
ì
nh
-244-
Đị
Đị
Đị
Đị
nh

nh
nh
nh
ngh
ngh
ngh
ngh
ĩ
ĩ
ĩ
ĩ
a
a
a
a
ch
ch
ch
ch




ng
ng
ng
ng
c
c
c

c
á
á
á
á
c
c
c
c
khu
khu
khu
khu
ô
ô
ô
ô
n
n
n
n
h
h
h
h
ì
ì
ì
ì
nh

nh
nh
nh
h
h
h
h
à
à
à
à
m
m
m
m
Giốngnhviệcđịnhnghĩachồngcáchàmthôngthờng,C++chophépđịnh
nghĩachồngcáckhuônhìnhhàm,tứclàcóthểđịnhnghĩamộthaynhiềukhuôn
hìnhhàmcócùngtênnhngvớicácthamsốkhácnhau.Điềuđósẽtạoranhiềuhọ
cáchàm(mỗikhuônhìnhhàmtơngứngvớimộthọcáchàm).Vídụcóbahọhàm
m in
:
(iv)
Họthứnhấtbaogồmcáchàmtìmgiátrịnhỏnhấttronghaigiátrị,
(v)Họthứhaitìmsốnhỏnhấttrongbasố,
(vi)
Họthứbatìmsốnhỏnhấttrongmộtmảng.
V
V
V
V

í
í
í
í
d
d
d
d




6.6
6.6
6.6
6.6
/*templat7.cpp*/
/*templat7.cpp*/
/*templat7.cpp*/
/*templat7.cpp*/
#include
<iostream.h>
#include<conio.h>
//khuônhình1
template
<class
T>
T
min(T
a,

T
b)
{
if(a
<
b)
return
a;
elsereturn
b;
}
//khuônhình2
template
<class
T>
T
min(T
a,
T
b,
T
c)
{
returnmin(min(a,b),c);
}
//khuônhình3
template
<class
T>
T

min
(T
*t,int
n)
{
T
res
=
t[0];
for(int
i=
1;
i<
n;
i++)
if
(res
>
t[i])
res
=
t[i];
returnres;
}
voidmain()
{
clrscr();
int
n=
12,

p=
15,
q=
2;
Khuônh
ì
nh
-245-
float
x=
3.5,
y=
4.25,
z=
0.25;
intt[6]
=
{2,
3,
4,-1,21};
charc[4]
=
{'w','q','a','Q'};
cout<<

min(n,p)
=
<<min(n,p)<<"\n";
//
khu

ônh
ì
nh
1
int
min(int,
int)
cout<<

min(n,p,q)
=
<<min(n,p,q)<<"\n";
//khuônhình2intmin(int,int,int)
cout<<

min(x,y)
=
<<min(x,y)<<"\n";
//
khu
ônh
ì
nh
1
float
min(float,
float)
cout<<

min(x,y,z)

=
<<min(x,y,z)<<"\n";
//
khu
ônh
ì
nh
2
floatm in(float,float,float)
cout<<

min(t,6)
=
<<min(t,6)<<"\n";
//khuônhình3intmin(int*,int)
cout<<

min(c,4)
=
<<min(c,4)<<"\n";
//
khu
ônh
ì
nh
3
charmin(char
*,
int)
getch();

}
min(n,p)=12
min(n,p,q)=2
min(x,y)=3.5
min(x,y,z)=0.25
min(t,6)=-1
min(c,4)=Q
Nh
Nh
Nh
Nh




n
n
n
n
x
x
x
x
é
é
é
é
t
t
t

t
Cũnggiốngnhđịnhnghĩachồngcáchàm,việcđịnhnghĩachồngcáckhuôn
hìnhhàmcóthểgâyrasựnhậpnhằngtrongviệcsảnsinhcáchàmthểhiện.Chẳng
hạnvớibốnhọhàmsauđây:
template
<class
T>
T
fct(T,
T)
{ }
template
<class
T>
T
fct(T
*,T)
{ }
template
<class
T>
T
fct(T,T*){ }
template
<claas
T>
T
fct(T
*,
T*){ }

Xétcáccâulệnhsauđây:
int
x;
int
y;
Khuônh
ì
nh
-246-
Lờigọi
fct(&x,&y)
cóthểtơngứngvớikhuônhìnhhàm1haykhuônhìnhhàm4.
C
C
C
C




th
th
th
th




ho
ho

ho
ho
á
á
á
á
c
c
c
c
á
á
á
á
c
c
c
c
h
h
h
h
à
à
à
à
m
m
m
m

th
th
th
th




hi
hi
hi
hi




n
n
n
n
Mộtkhuônhìnhhàmđịnhnghĩamộthọcáchàmdựatrênmộtđịnhnghĩa
chung,nóicáchkhácchúngthựchiệntheocùngmộtgiảithuật.Trongmộtsố
trờnghợp,sựtổngquátnàycóthểchịurủiro,chẳnghạnnhtrongtrờnghợp
ápdụngkhuônhìnhhàm
min
chokiểu
char
char
char
char

*nhđãnóiởtrên.Kháiniệmcụthể
hoá,đaramộtgiảiphápkhắcphụccácrủirokiểunhtrên.C++chophépta
cungcấp,ngoàiđịnhnghĩacủamộtkhuônhìnhhàm,địnhnghĩacủamộtsốcác
hàmchomộtsốkiểudữliệucủathamsố.Taxétchơngtrìnhvídụsauđây:
V
V
V
V
í
í
í
í
d
d
d
d




6.7
6.7
6.7
6.7
/*templat8.cpp*/
/*templat8.cpp*/
/*templat8.cpp*/
/*templat8.cpp*/
#include
<iostream.h>

#include<string.h>
#include<conio.h>
//khuônhìnhhàmmin
template
<class
T>
T
min
(Ta,
T
b)
{
if(a
<
b)
return
a;
elsereturn
b;
}
//hàmminchokiểuxâukýtự
char
*
min(char*cha,char*chb)
{
if
(strcmp(cha,chb)<0)returncha;
elsereturnchb;
}
voidmain()

{
clrscr();
int
n=
12,
p=
15;
char*adr1="DHBK",*adr2
="CD2D";
cout<<"min(n,
p)
=
"<<min(n,p)<<"\n";
//khuônhìnhhàm
cout<<"min(adr1,adr2)
=
"<<min(adr1,adr2)<<endl;
//hàmchar*min(char*,
Khuônh
ì
nh
-247-
//char*)
getch();
}
min(n,p)=12
min(adr1,adr2)=CD2D
Nhvậy,bảnchấtcủacụthểhoákhuônhìnhhàmlàđịnhnghĩacáchàmthông
thờngcócùngtênvớikhuônhìnhhàmđểgiảiquyếtmộtsốtrờnghợprủirokhi
taápdụngkhuônhìnhhàmchomộtsốkiểudữliệuđặcbiệtnàođó.

T
T
T
T




ng
ng
ng
ng
k
k
k
k
ế
ế
ế
ế
t
t
t
t
v
v
v
v





c
c
c
c
á
á
á
á
c
c
c
c
khu
khu
khu
khu
ô
ô
ô
ô
n
n
n
n
h
h
h
h

ì
ì
ì
ì
nh
nh
nh
nh
h
h
h
h
à
à
à
à
m
m
m
m
Mộtcáchtổngquát,tacóthểđịnhnghĩamộthaynhiềukhuônhìnhcùngtên,
mỗikhuônhìnhcócácthamsốkiểucũngnhlàcácthamsốbiểuthứcriêng.Hơn
nữa,cóthểcungcấpcáchàmthôngthờngvớicùngtênvớimộtkhuônhìnhhàm;
trongtrờnghợpnàytanóiđólàsựcụthểhoámộthàmthểhiện.
Trongtrờnghợptổngquátkhicóđồngthờicảhàmđịnhnghĩachồngvà
khuônhìnhhàm,chơngtrìnhdịchlựachọnhàmtơngứngvớimộtlờigọihàm
dựatrêncácnguyêntắcsauđây:
(vii)
Đầutiên,kiểmtratấtcảcáchàmthôngthờngcùngtênvàchúýđếnsự
tơngứngchínhxác;nếuchỉcómộthàmphùhợp,hàmđóđợcchọn;cònnếu

cónhiềuhàmcùngthoảmãn(cósựnhậpnhằng)sẽtạoramộtlỗibiêndịchvà
quátrìnhtìmkiếmbịgiánđoạn.
(viii)
Nếukhôngcóhàmthôngthờngnàotơngứngchínhxácvớilờigọi,khi
đótakiểmtratấtcảcáckhuônhìnhhàmcócùngtênvớilờigọi;nếuchỉcó
mộttơngứngchínhxácđợctìmthấy,hàmthểhiệntơngứngđợcsảnsinh
vàvấnđềđợcgiảiquyết;cònnếucónhiềuhơnmộtkhuônhìnhhàm(cósự
nhậpnhằng)điềuđósẽgâyralỗibiêndịchvàquátrìnhtìmkiếmbịngắt.
(ix)
Cuốicùng,nếukhôngcókhuônhìnhhàmphùhợp,takiểmtramộtlầnnữa
tấtcảcáchàmthôngthờngcùngtênvớilờigoi.Trongtrờnghợpnàychúng
taphảitìmkiếmsựtơngứngdựavàocảcácchuyểnkiểuchophéptrong
C/C++.
KHU
KHU
KHU
KHU
ô
ô
ô
ô
N
N
N
N
h
h
h
h
ì

ì
ì
ì
nh
nh
nh
nh
l
l
l
l




p
p
p
p
Khu
Khu
Khu
Khu
ô
ô
ô
ô
n
n
n

n
h
h
h
h
ì
ì
ì
ì
nh
nh
nh
nh
l
l
l
l




p
p
p
p
l
l
l
l
à

à
à
à
g
g
g
g
ì
ì
ì
ì
?
?
?
?
Bêncạnhkháiniệmkhuônhìnhhàm,C++cònchophépđịnhnghĩakhuôn
hìnhlớp.Cũnggiốngnhkhuônhìnhhàm,ởđâytachỉcầnviếtđịnhnghĩacác
khuônhìnhlớpmộtlầnrồisauđócóthểápdụngchúngvớicáckiểudữliệukhác
nhauđểđợccáclớpthểhiệnkhácnhau.
Khuônh
ì
nh
-248-
T
T
T
T





o
o
o
o
m
m
m
m




t
t
t
t
khu
khu
khu
khu
ô
ô
ô
ô
n
n
n
n
h

h
h
h
ì
ì
ì
ì
nh
nh
nh
nh
l
l
l
l




p
p
p
p
Tathờngtạoralớppointtheokiểu(ởđâytabỏquađịnhnghĩacủacác
hàmthànhphần):
classpoint
{
int
x,y;
public:

point(intabs=0,intord=0);
void
display();
//
};
Trongvídụnày,tađịnhnghĩamộtlớpcácđiểmcótoạđộnguyên.Nếumuốn
toạđộđiểmcókiểudữliệukhác(float,
float,
float,
float,
double,
double,
double,
double,
long,
long,
long,
long,
unsigned
unsigned
unsigned
unsigned
int
int
int
int
)taphải
địnhnghĩamộtlớpkhácbằngcáchthaythế,trongđịnhnghĩalớp
point
,từkhoá

int
int
int
int
bằngtừkhoátơngứngvớikiểudữliệumongmuốn.
Đểtránhsựtrùnglặptrongcáctìnhhuốngnhtrên,chơngtrìnhdịchC++
chophépđịnhnghĩamộtkhuônhìnhlớpvàsauđó,ápdụngkhuônhìnhlớpnàyvới
cáckiểudữliệukhácnhauđểthuđợccáclớpthểhiệnnhmongmuốn:
template
<class
T>
classpoint
{
T
x;
T
y;
public:
point
(T
abs=0,
T
ord=0);
void
display();
};
Cũnggiốngnhcáckhuônhìnhhàm,tậphợp
template<class
T>
xácđịnh

rằngđólàmộtkhuônhìnhtrongđócómộtthamsốkiểu
T
;Cũngcầnphảinhắclại
rằng,C++sửdụngtừkhoáclass
class
class
class
chỉđểnóirằng
T
đạidiệnchomộtkiểudữliệu
nàođó.Tiếptheođâytabànđếnviệcđịnhnghĩacáchàmthànhphầncủakhuôn
hìnhlớp.Ngờitaphânbiệthaitrờnghợp:(i)Khihàmthànhphầnđợcđịnh
nghĩabêntrongđịnhnghĩalớptrờnghợpnàykhôngcógìthayđổi.Xétđịnhnghĩa
hàmthiếtlậpsauđây:
template
<class
T>
classpoint
{
T
x;
T
y;
public:
point(Tabs=0,
T
ord=0)
{
Khuônh
ì

nh
-249-
x=
abs;
y=
ord;
}

};
(ii)Ngợclại,khiđịnhnghĩacủahàmthànhphầnnằmngoàiđịnhnghĩalớp,
khiđócầnphảinhắclạichochơngtrìnhdịchbiết:cácthamsốkiểucủakhuôn
hìnhlớp,cónghĩalàphảinhắclại:
template
<class
T>
trớcđịnhnghĩahàm,
còntêncủakhuônhìnhlớpđợcviếtnhlà
point<T>
Tómlại,dòngtiêuđềđầyđủchohàmthànhphần
display()
củakhuônhình
hàmpointnhsau:
template
<class
T>
void
point<T>::display()
Sauđâylàđịnhnghĩađầyđủcủakhuônhìnhlớppoint:
#include
<iostream.h>

//tạokhuônhìnhhàm
template
<class
T>
classpoint
{T
x,y;
public:
//địnhnghĩahàmthànhphầnởbêntrongkhuônhình
l
ớp
point(Tabs
=
0,
T
ord
=
0)
{
x=
abs;
y=
ord;
}
void
display();
};
//địnhnghĩahàmthànhphầnởbênngoà
i
khuônhình

l
ớp
template
<class
T>
void
point<T>::display()
{
cout<<"Toa
do:"<<x<<"
"<<y<<"\n";
}
S
S
S
S




d
d
d
d




ng
ng

ng
ng
khu
khu
khu
khu
ô
ô
ô
ô
n
n
n
n
h
h
h
h
ì
ì
ì
ì
nh
nh
nh
nh
l
l
l
l





p
p
p
p
Mộtkhikhuônhìnhlớppointđãđợcđịnhnghĩa,mộtkhaibáonh:
point<int>
ai;
Khuônh
ì
nh
-250-
khaibáomộtđốitợng
ai
cóhaithànhphầntoạđộlàkiểunguyên(
int
int
int
int
)
.Điều
đócónghĩalà
point<int>
cóvaitrònhmộtkiểudữliệulớp;ngờitagọinólà
mộtlớpthểhiệncủakhuônhìnhlớp
point
.Mộtcáchtổngquát,khiápdụngmột

kiểudữliệunàođóvớikhuônhìnhlớppointtasẽcóđợcmộtlớpthểhiệntơng
ứngvớikiểudữliệu.Nhvậy:
point<double>
ad;
địnhnghĩamộtđốitợng
ad
cócáctoạđộlàsốthực;cònvới
point<double>
đóngvaitròmộtlớpvàđợcgọilàmộtlớpthểhiệncủakhuônhìnhlớppoint.
Trongtrờnghợpcầnphảitruyềncácthamsốchocáchàmthiếtlập,talàm
bìnhthờng.Vídụ:
point<int>ai(3,5);
point<double>
ad(2.5,4.4);
V
V
V
V
í
í
í
í
d
d
d
d





s
s
s
s




d
d
d
d




ng
ng
ng
ng
khu
khu
khu
khu
ô
ô
ô
ô
n
n

n
n
h
h
h
h
ì
ì
ì
ì
nh
nh
nh
nh
l
l
l
l




p
p
p
p
Taxétvídụsau:
V
V
V

V
í
í
í
í
d
d
d
d




6.8
6.8
6.8
6.8
/*templat9.cpp*/
/*templat9.cpp*/
/*templat9.cpp*/
/*templat9.cpp*/
#include
<iostream.h>
#include<conio.h>
//tạomộtkhuônhình
l
ớp
template
<class
T>

classpoint
{
T
x,y;
public:
point(Tabs
=
0,
T
ord
=
0)
{
x=
abs;
y=
ord;
}
void
display()
{
cout<<"Toa
do:"<<x<<"
"<<y<<"\n";
}
};
voidmain()
{
clrscr();
Khuônh

ì
nh
-251-
point<int>ai(3,5);ai.display();
point<char>
ac('d','y');
ac.display();
point<double>
ad(3.5,2.3);
ad.display();
getch();
}
Toado:35
Toado:dy
Toado:3.52.3
C
C
C
C
á
á
á
á
c
c
c
c
tham
tham
tham

tham
s
s
s
s




trong
trong
trong
trong
khu
khu
khu
khu
ô
ô
ô
ô
n
n
n
n
h
h
h
h
ì

ì
ì
ì
nh
nh
nh
nh
l
l
l
l




p
p
p
p
Hoàntoàngiốngnhkhuônhìnhhàm,cáckhuônhìnhlớpcóthểcócáctham
sốkiểuvàthamsốbiểuthức.Trongphầnnàytabànvềcácthamsốkiểu;còncác
thamsốbiểuthứcsẽđợcnóitrongphầnsau.Tuycónhiềuđiểmgiốngnhaugiữa
khuônhìnhhàmvàkhuônhìnhlớp,nhngcácràngbuộcđốivớicáckiểuthamsố
lạikhôngnhnhau.
S
S
S
S





l
l
l
l




ng
ng
ng
ng
c
c
c
c
á
á
á
á
c
c
c
c
tham
tham
tham
tham

s
s
s
s




ki
ki
ki
ki




u
u
u
u
trong
trong
trong
trong
m
m
m
m





t
t
t
t
khu
khu
khu
khu
ô
ô
ô
ô
n
n
n
n
h
h
h
h
ì
ì
ì
ì
nh
nh
nh
nh

l
l
l
l




p
p
p
p
Xétvídụkhaibáosau:
template
<class
T,
class
U,
class
V>
//danhsáchbathamsốkiểu
classtry
{
T
x;
U
t[5];

V
fm1(int,U);


};
S
S
S
S




n
n
n
n
sinh
sinh
sinh
sinh
m
m
m
m




t
t
t
t

l
l
l
l




p
p
p
p
th
th
th
th




hi
hi
hi
hi




n
n

n
n
Mộtlớpthểhiệnđợckhaibáobằngcáchliệtkêđằngsautênkhuônhìnhlớp
cácthamsốthực(làtêncáckiểudữliệu)vớisốlợngbằngvớisốcácthamsố
trongdanhsách(
template< >
)củakhuônhìnhlớp.Sauđâyđaramộtsốvídụ
vềlớpthểhiệncủakhuônhìnhlớp
try
:
try<int,float,int>
//lớpthểhiệnvớibathamsốint,float,int
try
<int,int
*,
double>
//lớpthểhiệnvớibathamsốint,int
*
,double
Khuônh
ì
nh
-252-
try<char
*,
int,obj>
//lớpthểhiệnvớibathamsốchar*,int,obj
Trongdòngcuốitacuốigiảđịnh
obj
làmộtkiểudữliệuđãđợcđịnhnghĩa

trớcđó.Thậmchícóthểsửdụngcáclớpthểhiệnđểlàmthamsốthựcchocáclớp
thểhiệnkhác,chẳnghạn:
try<float,
point<int>,
double>
try
<point<int>,point<float>,
char
*>
Cầnchúýrằng,vấnđềtơngứngchínhxácđợcnóitớitrongcáckhuônhình
hàmkhôngcònhiệulựcvớicáckhuônhìnhlớp.Vớicáckhuônhìnhhàm,việcsản
sinhmộtthểhiệnkhôngchỉdựavàodanhsáchcácthamsốcótrong
template< >
màcòndựavàodanhsáchcácthamsốhìnhthứctrongtiêuđềcủa
hàm.
Mộtthamsốhìnhthứccủamộtkhuônhìnhhàmcóthểcókiểu,làmộtlớp
thểhiệnnàođó,chẳnghạn:
template
<class
T>
void
fct(point<T>)
{

}
Việckhởitạomớicáckiểudữliệumớivẫnápdụngđợctrongcáckhuônhình
lớp.Mộtkhuônhìnhlớpcóthểcócácthànhphần(dữliệuhoặchàm)static
static
static
static

.Trong
trờnghợpnày,cầnphảibiếtrằng,mỗithểhiệncủalớpcómộttậphợpcácthành
phầnstatic
static
static
static
củariêngmình:
C
C
C
C
á
á
á
á
c
c
c
c
tham
tham
tham
tham
s
s
s
s





bi
bi
bi
bi




u
u
u
u
th
th
th
th




c
c
c
c
trong
trong
trong
trong
khu

khu
khu
khu
ô
ô
ô
ô
n
n
n
n
h
h
h
h
ì
ì
ì
ì
nh
nh
nh
nh
l
l
l
l





p
p
p
p
Mộtkhuônhìnhlớpcóthểchứacácthamsốbiểuthức.Sovớikhuônhìnhhàm,
kháiniệmthamsốbiểuthứctrongkhuônhìnhlớpcómộtsốđiểmkhácbiệt:tham
sốthựctếtơngứngvớithamsốbiểuthứcphảilàmộthằngsố.
Giảsửrằngtamuốnđịnhnghĩamộtlớp
table
đểthaotáctrêncácbảngchứa
cácđốitợngcókiểubấtkỳ.Mộtcáchtựnhiêntanghĩngayđếnviệctạomột
khuônhìnhlớpvớimộtthamsốkiểu.Đồngthờicòncóthểdùngmộtthamsốthứ
haiđểxácđịnhsốthànhphầncủamảng.Trongtrờnghợpnày,địnhnghĩacủa
khuônhìnhlớpcódạngnhsau:
template
<class
T,
int
n>
classtable
{
T
tab[n];
public:

};
Danhsáchcácthamsố(
template< >
)chứahaithamsốvớiđặcđiểmkhác

nhauhoàntoàn:mộtthamsốkiểuđợcxácđinhbởitừkhoáclass
class
class
class
,mộtthamsố
Khuônh
ì
nh
-253-
biểuthứckiểu
int
>.Chúngtasẽphảichỉrõgiátrịcủachúngtrongkhaibáocáclớp
thểhiện.Chẳnghạn,lớpthểhiện:
table<int,4>
tơngứngvớikhaibáonhsau:
classtable<int,4>
{
inttab[4];
public:

};
Sauđâylàmộtvídụhoànchỉnh:
V
V
V
V
í
í
í
í

d
d
d
d




6.9
6.9
6.9
6.9
/*templat10.cpp*/
/*templat10.cpp*/
/*templat10.cpp*/
/*templat10.cpp*/
#include
<iostream.h>
#include<conio.h>
template
<class
T,
int
n>
classtable
{
T
tab[n];
public:
table()

{
cout<<"Taobang\n";}
T&
operator[](int
i)
{
returntab[i];
}
};
classpoint
{
int
x,y;
public:
point(intabs
=
1,
intord
=
1)
{
x=
abs;
y=
ord;
cout<<"Tao
diem"<<x<<"
"<<y<<"\n";
}
void

display()
{
cout<<"Toa
do:"<<x<<"
"<<y<<"\n";
Khuônh
ì
nh
-254-
}
};
voidmain()
{
clrscr();
table<int,
4>
ti;
for(int
i=
0;
i<
4;
i++)
ti[i]
=
i;
cout<<"ti:
";
for(i
=

0;
i<
4;
i++)
cout
<<ti[i]<<"
";
cout<<"\n";
table<point,
3>
tp;
for(i
=
0;
i<
3;
i++)
tp[i].display();
getch();
}
Taobang
ti:0123
Taodiem11
Taodiem11
Taodiem11
Taobang
Toado:11
Toado:11
Toado:11
T

T
T
T




ng
ng
ng
ng
qu
qu
qu
qu
á
á
á
á
t
t
t
t
v
v
v
v





khu
khu
khu
khu
ô
ô
ô
ô
n
n
n
n
h
h
h
h
ì
ì
ì
ì
nh
nh
nh
nh
l
l
l
l





p
p
p
p
Tacóthểkhaibáomộtsốtuỳýcácthamsốbiểuthứctrongdanhsáchcác
thamsốcủakhuônhìnhhàm.Cácthamsốnàycóthểxuấthiệnởbấtkỳnơinào
trongđịnhnghĩacủakhuônhìnhlớp.Khisảnsinhmộtlớpcócácthamsốbiểuthức,
cácthamsốthựctếtơngứngphảilàcácbiểuthứchằngphùhợpvớikiểudữliệu
đãkhaibáotrongdanhsáchcácthamsốhìnhthứccủakhuônhìnhlớp.
Khuônh
ì
nh
-255-
C
C
C
C




th
th
th
th





ho
ho
ho
ho
á
á
á
á
khu
khu
khu
khu
ô
ô
ô
ô
n
n
n
n
h
h
h
h
ì
ì
ì
ì

nh
nh
nh
nh
l
l
l
l




p
p
p
p
Khảnăngcụthểhoákhuônhìnhlớpcóđôichútkhácbiệtsovớikhuônhình
hàm.
Khuônhìnhlớpđịnhnghĩahọcáclớptrongđómỗilớpchứađồngthờiđịnh
nghĩacủachínhnóvàcáchàmthànhphần.Nhvậy,tấtcảcáchàmthànhphần
cùngtênsẽđợcthựchiệntheocùngmộtgiảithuật.Nếutamuốnchomộthàm
thànhphầnthíchứngvớimộttìnhhuốngcụthểcụthểnàođó,cóthểviếtmộtđịnh
nghĩakhácchonó.Sauđâylàmộtvídụcảitiếnkhuônhìnhlớppoint.ởđây
chúngtađãcụthểhoáhàmhiểnthị
display()
chotrờnghợpkiểudữliệu
char
char
char
char

:
V
V
V
V
í
í
í
í
d
d
d
d




6.10
6.10
6.10
6.10
/*templat11.cpp*/
/*templat11.cpp*/
/*templat11.cpp*/
/*templat11.cpp*/
#include
<iostream.h>
#include<conio.h>
//tạomộtkhuônhình
l

ớp
template
<class
T>
classpoint
{
T
x,y;
public:
point(Tabs
=
0,
T
ord
=
0)
{
x=
abs;
y=
ord;
}
void
display();
};
template
<class
T>
void
point<T>::display()

{
cout<<"Toa
do:"<<x<<"
"<<y<<"\n";
}
//Thêmmộthàmdisplaycụthểhoátrongtrờnghợpcácký
t

void
point<char>::display()
{
cout<<"Toa
do:"<<(int)x<<"
"<<(int)y<<"\n";
}
voidmain()
{
clrscr();
point<int>
ai(3,5);
ai.display();
Khuônh
ì
nh
-256-
point<char>ac('d','y');
ac.display();
point
<double>
ad(3.5,2.3);

ad.display();
getch();
}
Toado:35
Toado:100121
Toado:3.52.3
Tachúýdòngtiêuđềtrongkhaibáomộtthànhphầnđợccụthểhoá:
void
point<char>::display()
Khaibáonàynhắcchơngtrìnhdịchsửdùnghàmnàythaythếhàm
display(
)
củakhuônhìnhlớppoint(trongtrờnghợpgiátrịthựctếchothamsốkiểulà
char
char
char
char
).
Nh
Nh
Nh
Nh




n
n
n
n

x
x
x
x
é
é
é
é
t
t
t
t
(x)
Cóthểcụthểhoágiátrịcủatấtcảcácthamsố.Xétkhuônhìnhlớpsauđây:
template
<class
T,
int
n>
classtable
{
T
tab[n];
public:
table()
{cout<<"
Tao
bang\n";
}


};
Khiđó,chúngtacóthểviếtmộtđịnhnghĩacụthểhoáchohàmthiếtlậpcho
cácbảng10phầntửkiểupointnhsau:
table<point,10>::table( )
{ }
(xi)Cóthểcụthểhoámộthàmthànhphầnhaymộtlớp.Trongvídụ6.10
chơngtrình
template11.cpp
đãcụthểhoámộthàmthànhphầncủakhuôn
hìnhlớp.Nóichungcóthể:cụthểhoámộthaynhiềuhàmthànhphần,hoặc
khôngcầnthayđổiđịnhnghĩacủabảnthânlớp(thựctếcầnphảilàmnhvậy)
màcụthểhoábảnthânlớpbằngcáchđathêmđịnhnghĩa.Khảnăngthứhai
nàycódẫntớiviệcphảicụthểhoámộtsốhàmthànhphần.Chẳnghạn,saukhi
địnhnghĩakhuônhình
template<class
T>
classpoint
,tacóthểđịnh
Khuônh
ì
nh
-257-
nghĩamộtphiênbảncụthểchokiểudữliệu
point
thíchhợpvớithểhiện
point<char>
.Talàmnhsau:
class
point<char>
{

//địnhnghĩamới
};
S
S
S
S




gi
gi
gi
gi




ng
ng
ng
ng
nhau
nhau
nhau
nhau
c
c
c
c





a
a
a
a
c
c
c
c
á
á
á
á
c
c
c
c
l
l
l
l




p
p

p
p
th
th
th
th




hi
hi
hi
hi




n
n
n
n
Xétcâulệnhgángiữahaiđốitợng.Nhchúngtađãbiết,chỉcóthểthựchiện
đợcphépgánkhihaiđốitợngcócùngkiểu(vớitrờnghợpthừakếvấnđềđặc
biệthơnmộtchútnhngthựcchấtchỉlàchuyểnkiểungầmđịnhđốivớibiểuthức
vếphảicủalệnhgán).Trớcđây,tabiếtrằnghaiđốitợngcócùngkiểunếuchúng
đợckhaibáovớicùngmộttênlớp.Trongtrờnghợpkhuônhìnhlớp,nênhiểusự
cùngkiểuởđâynhthếnào?Thựctế,hailớpthểhiệntơngứngvớicùngmộtkiểu
nếucácthamsốkiểutơngứngnhaumộtcáchchínhxácvàcácthamsốbiểuthức
cócùnggiátrị.Nhvậy(giảthiếtrằngchúngtađãđịnhnghĩakhuônhìnhlớp

table
trongmục2.6)vớicáckhaibáo:
table<int,12>t1;
table
<float,12>
t2;
takhôngcóquyềnviết:
t2=
t1;
//không
t
ơngthíchgiữahaithamsốđầu
Cũngvậy,vớicáckhaibáo:
table<int,12>ta;
table<int,20>tb;
cũngkhôngđợcquyềnviết
ta
=
tb;
//giátr

thựccủahaithamsốsaukhácnhau.
Nhữngquitắcchặtchẽtrênnhằmlàmchophépgánngầmđịnhđợcthựchiện
chínhxác.Trờnghợpcócácđịnhnghĩachồngtoántửgán,cóthểkhôngnhấtthiết
phảituântheoquitắcđãnêutrên.Chẳnghạnhoàntoàncóthểthựchiệnđợcphép
gán
t2=
t1;
nếutacóđịnhnghĩahailớpthểhiện
table<int,

m>

table<float,n>

tronglớpthứhaicóđịnhnghĩachồngphépgánbằng.
C
C
C
C
á
á
á
á
c
c
c
c
l
l
l
l




p
p
p
p
th

th
th
th




hi
hi
hi
hi




n
n
n
n
v
v
v
v
à
à
à
à
c
c
c

c
á
á
á
á
c
c
c
c
khai
khai
khai
khai
b
b
b
b
á
á
á
á
o
o
o
o
b
b
b
b





n
n
n
n
b
b
b
b
è
è
è
è
Cáckhuônhìnhlớpcũngchophépkhaibáobạnbè.Bêntrongmộtkhuônhình
lớp,tacóthểthựchiệnbakiểukhaibáobạnbènhsau.

×