Giáo trình Lập trình hướng đối tượng với C++ - Chương 2: Những mở rộng của C++
Ch-¬ng 2
Nh÷ng më réng cña C++
Môc ®Ých ch-¬ng nµy:
Giíi thiÖu nh÷ng ®iÓm kh¸c biÖt chñ yÕu gi÷a C vµ C++
C¸c ®iÓm míi cña C++ so víi C (nh÷ng vÊn ®Ò c¬ b¶n nhÊt)
1.
2.
1. C¸c ®iÓm kh«ng t-¬ng thÝch gi÷a C++ vµ ANSI C
1.1 §Þnh nghÜa hµm
Trong ®Þnh nghÜa hµm, ANSI C cho phÐp hai kiÓu khai b¸o dßng tiªu ®Ò cña
hµm, trong khi ®ã C++ chØ chÊp nhËn mét c¸ch:
/*C++ kh«ng cã khai b¸o kiÓu nµy*/
double fexple(u,v)
int u;
/*c¶ C vµ C++ cho phÐp*/
double fexple(int u,double v)
int u;
double v;
double v;
1.2 Khai b¸o hµm nguyªn mÉu
Trong ANSI C, khi sö dông mét hµm ch-a ®-îc ®Þnh nghÜa tr-íc ®ã trong
cïng mét tÖp, ta cã thÓ:
kh«ng cÇn khai b¸o (khi ®ã ngÇm ®Þnh gi¸ trÞ tr¶ vÒ cña hµm lµ int)
3.
4.
chØ cÇn khai b¸o tªn hµm vµ gi¸ trÞ tr¶ vÒ, kh«ng cÇn danh s¸ch kiÓu cña
c¸c tham sè.
5. khai b¸o hµm nguyªn mÉu.
Víi C++, chØ cã ph-¬ng ph¸p thø 3 lµ chÊp nhËn ®-îc. Nãi c¸ch kh¸c, mét lêi
gäi hµm chØ ®-îc chÊp nhËn khi tr×nh biªn dÞch biÕt ®-îc kiÓu cña c¸c tham sè,
kiÓu cña gi¸ trÞ tr¶ vÒ. Mçi khi tr×nh biªn dÞch gÆp mét lêi gäi hµm, nã sÏ so s¸nh
c¸c kiÓu cña c¸c ®èi sè ®-îc truyÒn víi c¸c tham sè h×nh thøc t-¬ng øng. Trong
tr-êng hîp cã sù kh¸c nhau, cã thÓ thùc hiÖn mét sè chuyÓn kiÓu tù ®éng ®Ó cho
hµm nhËn ®-îc cã danh s¸ch c¸c tham sè ®óng víi kiÓu ®· ®-îc khai b¸o cña hµm.
Tuy nhiªn ph¶i tu©n theo nguyªn t¾c chuyÓn kiÓu tù ®éng sau ®©y:
char-->int-->longint-->float-->double
VÝ dô 2.1
double fexple (int, double) /*khai b¸o hµm fexple*/
....
-13-
C¸c më réng cña C++
main(){
int n;
char c;
double z,res1,res2,res3;
....
res1 = fexple(n,z); /* kh«ng cã chuyÓn ®æi kiÓu*/
res2 = fexple(c,z); /* cã chuyÓn ®æi kiÓu, tõ char (c) thµnh int*/
res3 = fexple(z,n); /* cã chuyÓn ®æi kiÓu, tõ double(z) thµnh int vµ tõ int(n)
thµnh double*/
....
}
Trong C++ b¾t buéc ph¶i cã tõ kho¸ void tr-íc tªn cña hµm trong phÇn khai
b¸o ®Ó chØ r»ng hµm kh«ng tr¶ vÒ gi¸ trÞ. Tr-êng hîp kh«ng cã, tr×nh biªn dÞch
ngÇm hiÓu kiÓu cña gi¸ trÞ tr¶ vÒ lµ int vµ nh- thÕ trong th©n hµm b¾t buéc ph¶i cã
c©u lÖnh return. §iÒu nµy hoµn toµn kh«ng cÇn thiÕt ®èi víi m« t¶ trong ng«n ng÷
C.
Thùc ra, c¸c kh¶ n¨ng võa m« t¶ kh«ng hoµn toµn lµ ®iÓm kh«ng t-¬ng thÝch
gi÷a C vµ C++ mµ ®ã chØ lµ sù “g¹n läc” c¸c ®iÓm yÕu vµ hoµn thiÖn c¸c mÆt cßn
ch-a hoµn chØnh cña C.
1.3 Sù t-¬ng thÝch gi÷a con trá void vµ c¸c con trá kh¸c
Trong ANSI C, kiÓu void * t-¬ng thÝch víi c¸c kiÓu trá kh¸c c¶ hai chiÒu.
Ch¼ng h¹n víi c¸c khai b¸o sau :
void *gen;
int *adj;
hai phÐp g¸n sau ®©y lµ hîp lÖ trong ANSI C:
gen = adj;
adj = gen;
Thùc ra, hai c©u lÖnh trªn ®· kÌm theo c¸c phÐp “chuyÓn kiÓu ngÇm ®Þnh”:
int* --->void* ®èi víi c©u lÖnh thø nhÊt, vµ
void* --->int* ®èi víi c©u lÖnh thø hai.
-14-
C¸c më réng cña C++
Trong C++, chØ cã chuyÓn ®æi kiÓu ngÇm ®Þnh tõ mét kiÓu trá tuú ý thµnh
void* lµ chÊp nhËn ®-îc, cßn muèn chuyÓn ®æi ng-îc l¹i, ta ph¶i thùc hiÖn chuyÓn
kiÓu t-êng minh nh- c¸ch viÕt sau ®©y:
gen = adj;
adj = (int *)gen;
2. C¸c kh¶ n¨ng vµo/ra míi cña C++
C¸c tiÖn Ých vµo/ra (hµm hoÆc macro) cña th- viÖn C chuÈn ®Òu cã thÓ sö dông
trong C++. §Ó sö dông c¸c hµm nµy chóng ta chØ cÇn khai b¸o tÖp tiªu ®Ò trong ®ã
cã chøa khai b¸o hµm nguyªn mÉu cña c¸c tiÖn Ých nµy.
Bªn c¹nh ®ã, C++ cßn cµi ®Æt thªm c¸c kh¶ n¨ng vµo/ra míi dùa trªn hai to¸n
tö “<<”(xuÊt) vµ “>>” (nhËp) víi c¸c ®Æc tÝnh sau ®©y:
®¬n gi¶n trong sö dông
6.
7. cã kh¶ n¨ng më réng ®èi víi c¸c kiÓu míi theo nhu cÇu cña ng-êi lËp
tr×nh.
Trong tÖp tiªu ®Ò iostream.h ng-êi ta ®Þnh nghÜa hai ®èi t-îng cout vµ cin
t-¬ng øng víi hai thiÕt bÞ chuÈn ra/vµo ®-îc sö dông cïng víi “<<” vµ “>>”. Th«ng
th-êng ta hiÓu cout lµ mµn h×nh cßn cin lµ bµn phÝm.
2.1 Ghi d÷ liÖu lªn thiÕt bÞ ra chuÈn (mµn h×nh) cout
Trong phÇn nµy ta xem xÐt mét sè vÝ dô minh ho¹ c¸ch sö dông cout vµ “<<”
®Ó ®-a th«ng tin ra mµn h×nh.
VÝ dô 2.2
Ch-¬ng tr×nh sau minh ho¹ c¸ch sö dông cout ®Ó ®-a ra mµn h×nh mét x©u ký
tù.
#include <iostream.h> /*ph¶i khai b¸o khi muèn sö dông cout*/
main()
{
cout << "Welcome C++";
}
Welcome C++
“<<” lµ mét to¸n tö hai ng«i, to¸n h¹ng ë bªn tr¸i m« t¶ n¬i kÕt xuÊt th«ng tin
(cã thÓ lµ mét thiÕt bÞ ngo¹i vi chuÈn hay lµ mét tËp tin ), to¸n h¹ng bªn ph¶i cña
“<<” lµ mét biÓu thøc nµo ®ã. Trong ch-¬ng tr×nh trªn, c©u lÖnh cout
<<"Welcome C++" ®-a ra mµn h×nh x©u ký tù “Welcome C++”.
-15-
C¸c më réng cña C++
VÝ dô 2.3
Sö dông cout vµ “<<” ®-a ra c¸c gi¸ trÞ kh¸c nhau:
#include <iostream.h> /*ph¶i khai b¸o khi muèn sö dông cout*/
void main() {
int n = 25;
cout << "Value : ";
cout << n;
}
Value : 25
Trong vÝ dô nµy chóng ta ®· sö dông to¸n tö “<<” ®Ó in ra mµn h×nh ®Çu tiªn lµ
mét x©u ký tù, sau ®ã lµ mét sè nguyªn. Chøc n¨ng cña to¸n tö “<<” râ rµng lµ
kh¸c nhau trong hai lÇn kÕt xuÊt d÷ liÖu: víi c©u lÖnh thø nhÊt, chØ ®-a ra mµn h×nh
mét d·y c¸c ký tù, ë c©u lÖnh sau, ®· sö dông mét khu«n mÉu ®Ó chuyÓn ®æi mét
gi¸ trÞ nhÞ ph©n thµnh mét chuçi c¸c ký tù ch÷ sè. ViÖc mét to¸n tö cã nhiÒu vai trß
kh¸c nhau liªn quan ®Õn mét kh¸i niÖm míi trong C++, ®ã lµ “§Þnh nghÜa chång
to¸n tö”. §iÒu nµy sÏ ®-îc ®Ò cËp ®Õn trong ch-¬ng 4.
VÝ dô 2.4
Trong vÝ dô nµy ta gép c¶ hai c©u lÖnh kÕt xuÊt trong vÝ dô 2.3 thµnh mét c©u
lÖnh phøc t¹p h¬n, tuy kÕt qu¶ kh«ng kh¸c tr-íc:
#include <iostream.h> /*ph¶i khai b¸o khi muèn sö dông cout*/
void main() {
int n = 25;
cout << "Value : " << n;
}
Value : 25
C¸c kh¶ n¨ng viÕt ra trªn cout.
2.2
Chóng ta võa xem xÐt mét vµi vÝ dô viÕt mét x©u ký tù, mét sè nguyªn. Mét
c¸ch tæng qu¸t, chóng ta cã thÓ sö dông to¸n tö “<<” cïng víi cout ®Ó ®-a ra mµn
h×nh gi¸ trÞ cña mét biÓu thøc cã c¸c kiÓu sau:
kiÓu d÷ liÖu c¬ së ( char, int, float, double),
8.
9. x©u ký tù: (char *),
10.
con trá (trõ con trá char *)
-16-
C¸c më réng cña C++
Trong tr-êng hîp muèn ®-a ra ®Þa chØ biÕn x©u ký tù ph¶i thùc hiÖn phÐp
chuyÓn kiÓu t-êng minh, ch¼ng h¹n (char *) --> (void *).
XÐt vÝ dô sau ®©y:
VÝ dô 2.4
#include <iostream.h>
void void main(){
int n = 25;
long p = 250000;
unsigned q = 63000;
char c = 'a';
float x = 12.3456789;
double y = 12.3456789e16;
char * ch = "Welcome C++";
int *ad = &n;
cout <<"Value of n : " << n <<"\n";
cout <<"Value of p : " << p <<"\n";
cout <<"Value of c : " << c <<"\n";
cout <<"Value of q : " << q <<"\n";
cout <<"Value of x : " << x <<"\n";
cout <<"Value of y : " << y <<"\n";
cout <<"Value of ch : " << ch <<"\n";
cout <<"Addrese of n : " << ad <<"\n";
cout <<"Addrese de ch : " << (void *)ch <<"\n";
}
Value of n : 25
Value of p : 250000
Value of c : a
Value of q : 63000
Value of x : 12.345679
Value of y : 1.234567e+17
Value of ch : Welcome C++
Addrese of n : 0xfff2
Addrese de ch : 0x00b2
-17-
C¸c më réng cña C++
2.3 §äc d÷ liÖu tõ thiÕt bÞ vµo chuÈn (bµn phÝm) cin
NÕu nh- cout dïng ®Ó chØ thiÕt bÞ ra chuÈn, th× cin ®-îc dïng ®Ó chØ mét
thiÕt bÞ vµo chuÈn. Mét c¸ch t-¬ng tù, to¸n tö “>>” ®-îc dïng kÌm víi cin ®Ó nhËp
vµo c¸c gi¸ trÞ; hai c©u lÖnh
int n;
cin >> n;
yªu cÇu ®äc c¸c ký tù trªn bµn phÝm vµ chuyÓn chóng thµnh mét sè nguyªn vµ
g¸n cho biÕn n.
Gièng nh- cout vµ “<<”, cã thÓ nhËp nhiÒu gi¸ trÞ cïng kiÓu hay kh¸c kiÓu
b»ng c¸ch viÕt liªn tiÕp tªn c¸c biÕn cÇn nhËp gi¸ trÞ cïng víi “>>” ngay sau cin.
Ch¼ng h¹n:
int n;
float p;
char c;
cin >> c >> n >> p;
Cã thÓ sö dông to¸n tö “>>” ®Ó nhËp d÷ liÖu cho c¸c biÕn cã kiÓu char, int,
float, double vµ char *.
Gièng víi hµm scanf(), cin tu©n theo mét sè qui -íc dïng trong viÖc ph©n
tÝch c¸c ký tù:
C¸c gi¸ trÞ sè ®-îc ph©n c¸ch bëi: SPACE, TAB, CR, LF. Khi gÆp mét ký
tù “kh«ng hîp lÖ” ( dÊu “.” ®èi víi sè nguyªn, ch÷ c¸i ®èi víi sè, ...) sÏ
kÕt thóc viÖc ®äc tõ cin; ký tù kh«ng hîp lÖ nµy sÏ ®-îc xem xÐt trong
lÇn ®äc sau.
(i)
(ii) §èi víi gi¸ trÞ x©u ký tù, dÊu ph©n c¸ch còng lµ SPACE, TAB,CR, cßn
®èi víi gi¸ trÞ ký tù, dÊu ph©n c¸ch lµ ký tù CR. Trong hai tr-êng hîp nµy
kh«ng cã kh¸i niÖm “ký tù kh«ng hîp lÖ”. M· sinh ra do bÊm phÝm Enter
cña lÇn nhËp tr-íc vÉn ®-îc xÐt trong lÇn nhËp x©u/ký tù tiÕp theo vµ do
vËy sÏ cã “nguy c¬ ” kh«ng nhËp ®-îc ®óng gi¸ trÞ mong muèn khi ®-a ra
lÖnh nhËp x©u ký tù hoÆc ký tù ngay sau c¸c lÖnh nhËp c¸c gi¸ trÞ kh¸c.
Gi¶i ph¸p kh¾c phôc vÊn ®Ò nµy ®Ó ®¶m b¶o c«ng viÖc diÔn ra ®óng theo ý
lµ tr-íc mçi lÇn gäi lÖnh nhËp d÷ liÖu cho x©u/ký tù ta sö dông mét trong
hai chØ thÞ sau ®©y:
fflush(stdin); //khai b¸o trong stdio.h
cin.clear(); //hµm thµnh phÇn cña líp ®Þnh nghÜa ®èi t-îng cin
-18-
C¸c më réng cña C++
Ta tham kh¶o ch-¬ng tr×nh sau:
VÝ dô 2.6
#include <iostream.h>
#include <conio.h>
void main() {
int n;
float x;
char t[81];
clrscr();
do {
cout << "Nhap vao mot so nguyen, mot xau, mot so thuc : ";
cin >> n >> t >> x;
cout << "Da nhap " << n << "," << t << " va " << x << "\n";
} while (n);
}
Nhap vao mot so nguyen, mot xau, mot so thuc : 3 long 3.4
Da nhap 3,long va 3.4
Nhap vao mot so nguyen, mot xau, mot so thuc : 5 hung 5.6
Da nhap 5,hung and 5.6
Nhap vao mot so nguyen, mot xau, mot so thuc : 0 4
3
Da nhap 0,4 va 3
Nh÷ng tiÖn Ých cho ng-êi lËp tr×nh
3.1 Chó thÝch cuèi dßng
3.
Mäi ký hiÖu ®i sau “//” cho ®Õn hÕt dßng ®-îc coi lµ chó thÝch, ®-îc ch-¬ng
tr×nh dÞch bá qua khi biªn dÞch ch-¬ng tr×nh.
XÐt vÝ dô sau:
cout << "Xin chao\n"; //lêi chµo hái
Th-êng ta sö dông chó thÝch cuèi dßng khi muèn gi¶i thÝch ý nghÜa cña mét
c©u lÖnh g× ®ã. §èi víi mét ®o¹n ch-¬ng tr×nh kiÓu chó thÝch giíi h¹n bëi “/*” vµ
“*/” cho phÐp m« t¶ ®-îc nhiÒu th«ng tin h¬n.
-19-
C¸c më réng cña C++
3.2 Khai b¸o mäi n¬i
Trong C++ kh«ng nhÊt thiÕt ph¶i nhãm lªn ®Çu c¸c khai b¸o ®Æt bªn trong mét
hµm hay mét khèi lÖnh, mµ cã thÓ ®Æt xen kÏ víi c¸c lÖnh xö lý. VÝ dô.
{
int n;
n=23;
cout <<n<<"\n";
...
int *p=&n;
cout <<p<<"\n";
...
}
Gi¸ trÞ khëi ®Çu cho c¸c biÕn cã thÓ thay ®æi t¹i c¸c thêi ®iÓm ch¹y ch-¬ng
tr×nh kh¸c nhau.
Mét vÝ dô minh ho¹ cho kh¶ n¨ng ®Þnh nghÜa kh¾p mäi n¬i lµ cã thÓ khai b¸o
c¸c biÕn ®iÒu khiÓn ngay bªn trong c¸c vßng lÆp nÕu biÕn ®ã ch-a ®-îc khai b¸o
tr-íc ®ã trong cïng khèi lÖnh còng nh- kh«ng ®-îc khai b¸o l¹i ë phÇn sau. Xem
®o¹n ch-¬ng tr×nh sau:
{
... //ch-a cã i
for(int i=0;...;...)
... //kh«ng ®-îc khai b¸o i
}
3.3 To¸n tö ph¹m vi “::”
B×nh th-êng, biÕn côc bé che lÊp biÕn toµn côc cïng tªn. Ch¼ng h¹n:
#include <iostream.h>
int x;
main() {
int x = 10; //x côc bé
cout<<x<<“\n”;//x côc bé
}
-20-
C¸c më réng cña C++
Trong nh÷ng tr-êng hîp cÇn thiÕt, khi muèn truy xuÊt tíi biÕn toµn côc ph¶i sö
dông to¸n tö “::” tr-íc tªn biÕn:
#include <iostream.h>
int x;
main() {
int x = 10; //x côc bé
::x = 10; //x toµn côc
cout<<x<<“\n”;//x côc bé
cout<<::x<<“\n”;//x toµn côc
}
Hµm inline
4.
Trong C++ cã thÓ ®Þnh nghÜa c¸c hµm ®-îc thay thÕ trùc tiÕp thµnh m· lÖnh
m¸y t¹i chç gäi (inline) mçi lÇn ®-îc tham chiÕu. §iÓm nµy rÊt gièng víi c¸ch ho¹t
®éng cña c¸c macro cã tham sè trong C. ¦u ®iÓm cña c¸c hµm inline lµ chóng
kh«ng ®ßi hái c¸c thñ tôc bæ sung khi gäi hµm vµ tr¶ gi¸ trÞ vÒ. Do vËy hµm inline
®-îc thùc hiÖn nhanh h¬n so víi c¸c hµm th«ng th-êng.
Mét hµm inline ®-îc ®Þnh nghÜa vµ ®-îc sö dông gièng nh- b×nh th-êng.
§iÓm kh¸c nhau duy nhÊt lµ ph¶i ®Æt m« t¶ inline tr-íc khai b¸o hµm.
XÐt vÝ dô sau ®©y:
VÝ dô 2.7
#include <iostream.h>
#include <math.h>
#include <conio.h>
inline double norme(double vec[3]); // khai b¸o hµm inline
void main(){
clrscr();
double v1[3],v2[3];
int i;
for(i=0;i<3;i++) {
v1[i]=i;v2[i]=2*i-1;}
cout <<"norme cua v1 : "<<norme(v1) <<" - norme cua v2 : "<<norme(v2);
-21-
C¸c më réng cña C++
getch();
}
/*§Þnh nghÜa hµm inline*/
inline double norme(double vec[3])
int i;double s=0;
for(i=0;i<3;i++)
s+=vec[i]*vec[i];
return(sqrt(s));
}
{
norme cua v1 : 2.236068 - norme cua v2 : 3.316625
Hµm norme() nh»m môc ®Ých tÝnh chuÈn cña vector víi ba thµnh phÇn.
Tõ kho¸ inline yªu cÇu ch-¬ng tr×nh biªn dÞch xö lý hµm norme kh¸c víi c¸c
hµm th«ng th-êng. Cô thÓ lµ, mçi lÇn gäi norme(), tr×nh biªn dÞch ghÐp trùc tiÕp
c¸c chØ thÞ t-¬ng øng cña hµm vµo trong ch-¬ng tr×nh (ë d¹ng ng«n ng÷ m¸y). Do
®ã c¬ chÕ qu¶n lý lêi gäi vµ trë vÒ kh«ng cÇn n÷a (kh«ng cÇn l-u ng÷ c¶nh, sao
chÐp c¸c th«ng sè...), nhê vËy tiÕt kiÖm thêi gian thùc hiÖn. Bªn c¹nh ®ã c¸c chØ thÞ
t-¬ng øng sÏ ®-îc sinh ra mçi khi gäi hµm do ®ã chi phÝ l-u tr÷ t¨ng lªn khi hµm
®-îc gäi nhiÒu lÇn.
§iÓm bÊt lîi khi sö dông c¸c hµm inline lµ nÕu chóng qu¸ lín vµ ®-îc gäi
th-êng xuyªn th× kÝch th-íc ch-¬ng tr×nh sÏ t¨ng lªn rÊt nhanh. V× lý do nµy, chØ
nh÷ng hµm ®¬n gi¶n, kh«ng chøa c¸c cÊu tróc lÆp míi ®-îc khai b¸o lµ hµm inline.
ViÖc sö dông hµm inline so víi c¸c macro cã tham sè cã hai ®iÓm lîi. Tr-íc
hÕt hµm inline cung cÊp mét c¸ch cã cÊu tróc h¬n khi më réng c¸c hµm ®¬n gi¶n
thµnh hµm inline. Thùc tÕ cho thÊy khi t¹o mét macro cã tham sè th-êng hay quªn
c¸c dÊu ®ãng ngoÆc, rÊt cÇn ®Õn ®Ó ®¶m b¶o sù më réng néi tuyÕn riªng trong mçi
tr-êng hîp. Víi macro cã thÓ g©y ra hiÖu øng phô hoÆc bÞ h¹n chÕ kh¶ n¨ng sö
dông. Ch¼ng h¹n víi macro:
#define square(x) {x++*x++}
Víi lêi gäi
square(a)
víi a lµ biÕn sÏ s¶n sinh ra biÓu thøc a++*a++ vµ kÕt qu¶ lµ lµm thay ®æi gi¸ trÞ
cña biÕn a tíi hai lÇn.
Cßn lêi gäi
-22-
C¸c më réng cña C++
square (3)
sÏ g©y lçi biªn dÞch v× ta kh«ng thÓ thùc hiÖn c¸c phÐp to¸n t¨ng gi¶m trªn c¸c
to¸n h¹ng lµ h»ng sè.
ViÖc sö dông hµm inline nh- mét gi¶i ph¸p thay thÕ sÏ tr¸nh ®-îc c¸c t×nh
huèng nh- thÕ.
Ngoµi ra, c¸c hµm inline cã thÓ ®-îc tèi -u bëi ch-¬ng tr×nh biªn dÞch.
§iÒu quan träng lµ ®Æc t¶ inline chØ lµ mét yªu cÇu, chø kh«ng ph¶i lµ mét chØ
thÞ ®èi víi tr×nh biªn dÞch. NÕu v× mét lý do nµo ®ã tr×nh biªn dÞch kh«ng thÓ ®¸p
øng ®-îc yªu cÇu (ch¼ng h¹n khi bªn trong ®Þnh nghÜa hµm inline cã c¸c cÊu tróc
lÆp) th× hµm sÏ ®-îc biªn dÞch nh- mét hµm b×nh th-êng vµ yªu cÇu inline sÏ bÞ bá
qua.
Hµm inline ph¶i ®-îc khai b¸o bªn trong tÖp tin nguån chøa c¸c hµm sö dông
nã. Kh«ng thÓ dÞch t¸ch biÖt c¸c hµm inline. 1
Tham chiÕu
5.
Ng«n ng÷ C++ giíi thiÖu mét kh¸i niÖm míi “reference” t¹m dÞch lµ “tham
chiÕu”. VÒ b¶n chÊt, tham chiÕu lµ “bÝ danh” cña mét vïng nhí ®-îc cÊp ph¸t cho
mét biÕn nµo ®ã.
Mét tham chiÕu cã thÓ lµ mét biÕn, tham sè h×nh thøc cña hµm hay dïng lµm
gi¸ trÞ tr¶ vÒ cña mét hµm. C¸c phÇn tiÕp sau lÇn l-ît giíi thiÖu c¸c kh¶ n¨ng cña
tham chiÕu ®-îc sö dông trong ch-¬ng tr×nh viÕt b»ng ng«n ng÷ C++.
5.1 Tham chiÕu tíi mét biÕn
XÐt hai chØ thÞ:
int n;
int &p = n;
Trong chØ thÞ thø hai, dÊu “&” ®Ó x¸c ®Þnh p lµ mét biÕn tham chiÕu cßn dÊu “=”
vµ tªn biÕn n ®Ó x¸c ®Þnh vïng nhí mµ p tham chiÕu tíi. Lóc nµy c¶ hai ®Þnh danh
p vµ n cïng x¸c ®Þnh vïng nhí ®-îc cÊp ph¸t cho biÕn n. Nh- vËy c¸c chØ thÞ sau:
n =3;
cout <<p;
1 “Biªn dÞch t¸ch biÖt” cho phÐp khai b¸o hµm trong mét tÖp tiªu ®Ò, cßn ®Þnh nghÜa
hµm ®ã l¹i ë trong tËp tin ch-¬ng tr×nh sö dông hµm.
-23-
C¸c më réng cña C++
cho kÕt qu¶ 3 trªn thiÕt bÞ hiÓn thÞ.
XÐt vÒ b¶n chÊt tham chiÕu vµ tham trá gièng nhau v× cïng chØ ®Õn c¸c ®èi
t-îng cã ®Þa chØ, cïng ®-îc cÊp ph¸t ®Þa chØ khi khai b¸o. Nh-ng c¸ch sö dông
chóng th× kh¸c nhau. Khi nãi ®Õn tham chiÕu “&p” ta ph¶i g¾n nã víi mét biÕn nµo
®ã ®· khai b¸o qua “&p=n”, trong khi ®ã khai b¸o con trá “*p” kh«ng nhÊt thiÕt
ph¶i khëi t¹o gi¸ trÞ cho nã. Trong ch-¬ng tr×nh biÕn trá cã thÓ tham chiÕu ®Õn
nhiÒu biÕn kh¸c nhau cßn biÕn tham chiÕu th× “v¸n ®· ®ãng thuyÒn” tõ khi khai b¸o,
cã nghÜa lµ sau khi khëi t¹o cho tham chiÕu g¾n víi mét biÕn nµo ®ã råi th× ta
kh«ng thÓ thay ®æi ®Ó g¾n tam chiÕu víi mét biÕn kh¸c.
XÐt c¸c chØ thÞ sau:
VÝ dô 2.8
int n=3,m=4;
int *p;
p=&n; //p chØ ®Õn n
*p=4; //g¸n gi¸ trÞ cña m cho n th«ng qua con trá p
...
p=&m; //cho p chØ ®Õn m
int &q=n; //khai b¸o tham chiÕu q chØ ®Õn n
q=4; //g¸n cho biÕn n gi¸ trÞ 4
...
q=m; //g¸n gi¸ trÞ cña biÕn m cho biÕn n.
Nãi mét c¸ch ®¬n gi¶n, tham chiÕu cña mét biÕn gièng nh- bÝ danh cña mét
con ng-êi nµo ®ã. Cã nghÜa lµ ®Ó chØ ®Õn mét con ng-êi cô thÓ nµo ®ã, ta cã thÓ
®ång thêi sö dông tªn cña anh ta hoÆc bÝ danh. Do vËy, ®Ó truy nhËp ®Õn vïng nhí
t-¬ng øng víi mét biÕn, chóng ta cã thÓ sö dông hoÆc lµ tªn biÕn hoÆc lµ tªn tham
chiÕu t-¬ng øng. §èi víi con ng-êi, bÝ danh bao giê còng nh»m nãi ®Õn mét ng-êi
®· tån t¹i, vµ nh- vËy tham chiÕu còng ph¶i ®-îc khai b¸o vµ khëi t¹o sau khi biÕn
®-îc khai b¸o. Ch-¬ng tr×nh sau ®©y sÏ g©y lçi biªn dÞch do tham chiÕu y ch-a
®-îc khëi t¹o.
VÝ dô 2.9
Ch-¬ng tr×nh sai
#include <iostream.h>
void main() {
int x=3, &y;//lçi v× y ph¶i ®-îc khëi t¹o
-24-
C¸c më réng cña C++
cout <<" x = "<<x<<"\n"
<<" y = "<<y<<"\n";
y = 7;
cout <<" x = "<<x<<"\n"
<<" y = "<<y<<"\n";
}
Ch-¬ng tr×nh ®óng nh- sau:
#include <iostream.h>
void main() {
int x=3, &y=x;//y b©y giê lµ mét “bÝ danh” cña x
cout <<" x = "<<x<<"\n"
<<" y = "<<y<<"\n";
y = 7;
cout <<" x = "<<x<<"\n"
<<" y = "<<y<<"\n";
}
x = 3
y = 3
x = 7
y = 7
L-u ý cuèi cïng lµ kh«ng thÓ g¾n mét tham chiÕu víi mét h»ng sè trõ tr-êng
hîp cã tõ kho¸ const ®øng tr-íc khai b¸o tham chiÕu. DÔ dµng kiÓm tra c¸c nhËn
xÐt sau:
int &p =3; //kh«ng hîp lÖ
const int & p =3; //hîp lÖ
5.2 TruyÒn tham sè cho hµm b»ng tham chiÕu
Trong C, c¸c tham sè vµ gi¸ trÞ tr¶ vÒ cña mét hµm ®-îc truyÒn b»ng gi¸ trÞ.
§Ó gi¶ lËp c¬ chÕ truyÒn tham biÕn ta ph¶i sö dông con trá.
Trong C++, viÖc dïng kh¸i niÖm tham chiÕu trong khai b¸o tham sè h×nh thøc
cña hµm sÏ yªu cÇu ch-¬ng tr×nh biªn dÞch truyÒn ®Þa chØ cña biÕn cho hµm vµ hµm
sÏ thao t¸c trùc tiÕp trªn c¸c biÕn ®ã. Ch-¬ng tr×nh sau ®-a ra ba c¸ch viÕt kh¸c
nhau cña hµm thùc hiÖn viÖc ho¸n ®æi néi dung cña hai biÕn.
-25-
C¸c më réng cña C++
VÝ dô 2.10
/*swap.cpp*/
#include <conio.h>
#include <iostream.h>
/*Hµm swap1 ®-îc gäi víi c¸c tham sè ®-îc truyÒn theo tham trÞ*/
void swap1(int x, int y) {
int temp = x;
x = y;
y = temp;
}
/*Hµm swap2 thùc hiÖn viÖc truyÒn tham sè b»ng tham trá*/
void swap2(int *x, int *y) {
int temp = *x;
*x = *y;
*y = temp;
}
/*Hµm swap3 thùc hiÖn viÖc truyÒn tham sè b»ng tham chiÕu*/
void swap3(int &x, int &y) {
int temp = x;
x = y;
y = temp;
}
void main() {
int a=3, b=4;
clrscr();
cout <<"Truoc khi goi swap1:\n";
cout<<"a = "<<a<<" b = "<<b<<"\n";
swap1(a,b);
cout <<"Sau khi goi swap:\n";
cout<<"a = "<<a<<" b = "<<b<<"\n";
-26-
C¸c më réng cña C++
a=3; b =4;
cout <<"Truoc khi goi swap2:\n";
cout<<"a = "<<a<<" b = "<<b<<"\n";
swap2(&a,&b);
cout <<"Sau khi goi swap2:\n";
cout<<"a = "<<a<<" b = "<<b<<"\n";
a=3;b=4;
cout <<"Truoc khi goi swap3:\n";
cout<<"a = "<<a<<" b = "<<b<<"\n";
swap3(a,b);
cout <<"Sau khi goi swap3:\n";
cout<<"a = "<<a<<" b = "<<b<<"\n";
getch();
}
Truoc khi goi swap1:
a = 3 b = 4
Sau khi goi swap1:
a = 3 b = 4
Truoc khi goi swap2
a = 3 b = 4
Sau khi goi swap2:
a = 4 b = 3
Truoc khi goi swap3:
a = 3 b = 4
Sau khi goi swap3:
a = 4 b = 3
Trong ch-¬ng tr×nh trªn, ta truyÒn tham sè a,b cho hµm swap1() theo tham trÞ
cho nªn gi¸ trÞ cña chóng kh«ng thay ®æi tr-íc vµ sau khi gäi hµm.
Gi¶i ph¸p ®-a ra trong hµm swap2() lµ thay v× truyÒn trùc tiÕp gi¸ trÞ hai biÕn
a vµ b ng-êi ta truyÒn ®Þa chØ cña chóng råi th«ng qua c¸c ®Þa chØ nµy ®Ó x¸c ®Þnh
gi¸ trÞ biÕn. B»ng c¸ch ®ã gi¸ trÞ cña hai biÕn a vµ b sÏ ho¸n ®æi cho nhau sau lêi
gäi hµm. Kh¸c víi swap2(), hµm swap3() ®-a ra gi¶i ph¸p sö dông tham chiÕu.
C¸c tham sè h×nh thøc cña hµm swap3() b©y giê lµ c¸c tham chiÕu ®Õn c¸c tham
sè thùc ®-îc truyÒn cho hµm. Nhê vËy mµ gi¸ trÞ cña hai tham sè thùc a vµ b cã thÓ
ho¸n ®æi ®-îc cho nhau.
-27-
C¸c më réng cña C++
Cã mét vÊn ®Ò mµ ch¾c r»ng b¹n ®äc sÏ ph©n v©n: “lµm thÕ nµo ®Ó khëi t¹o
c¸c tham sè h×nh thøc lµ tham chiÕu”. Xin th-a r»ng ®iÒu ®ã ®-îc thùc hiÖn tù ®éng
trong mçi lêi gäi hµm chø kh«ng ph¶i trong ®Þnh nghÜa. Tõ ®ã n¶y sinh thªm mét
nhËn xÐt quan träng: “tham sè øng víi tham sè h×nh thøc lµ tham chiÕu ph¶i lµ biÕn
trõ tr-êng hîp cã tõ kho¸ const ®øng tr-íc khai b¸o tham sè h×nh thøc”. Ch¼ng h¹n
kh«ng thÓ thùc hiÖn lêi gäi hµm sau:
swap3(2,3);
B¹n ®äc cã thÓ xem thªm phÇn “Hµm thiÕt lËp sao chÐp l¹i” ®Ó thÊy ®-îc Ých
lîi to lín cña viÖc truyÒn tham sè cho hµm b»ng tham chiÕu.
Chó ý: khi muèn truyÒn b»ng tham biÕn mét biÕn trá th× viÕt nh- sau:
int* & adr; //adr lµ mét tham chiÕu tíi mét biÕn trá chØ ®Õn mét biÕn nguyªn.
5.3 Gi¸ trÞ tr¶ vÒ cña hµm lµ tham chiÕu
§Þnh nghÜa cña hµm cã d¹ng nh- sau:
<type> & fct( ...) {
...
return <bien co pham vi toan cuc>;
}
Trong tr-êng hîp nµy biÓu thøc ®-îc tr¶ l¹i trong c©u lÖnh return ph¶i lµ tªn
cña mét biÕn x¸c ®Þnh tõ bªn ngoµi hµm, bëi v× chØ khi ®ã míi cã thÓ sö dông ®-îc
gi¸ trÞ cña hµm. Khi ta tr¶ vÒ mét tham chiÕu ®Õn mét biÕn côc bé khai b¸o bªn
trong hµm, biÕn côc bé nµy sÏ bÞ mÊt ®i khi kÕt thóc thùc hiÖn hµm vµ do vËy, tham
chiÕu cña hµm còng kh«ng cßn cã ý nghÜa n÷a.
Khi gi¸ trÞ tr¶ vÒ cña hµm lµ tham chiÕu, ta cã thÓ gÆp c¸c c©u lÖnh g¸n “kú dÞ”
trong ®ã vÕ tr¸i lµ mét lêi gäi hµm chø kh«ng ph¶i lµ tªn cña mét biÕn. §iÒu nµy
hoµn toµn hîp lý, bëi lÏ b¶n th©n hµm ®ã cã gi¸ trÞ tr¶ vÒ lµ mét tham chiÕu. Nãi
c¸ch kh¸c, vÕ tr¸i cña lÖnh g¸n (biÓu thøc g¸n) cã thÓ lµ lêi gäi ®Õn mét hµm cã gi¸
trÞ tr¶ vÒ lµ mét tham chiÕu.
XÐt vÝ dô sau ®©y:
VÝ dô 2.11
/*fr.cpp*/
#include <iostream.h>
#include <conio.h>
int a[5];
-28-
C¸c më réng cña C++
int &fr(int *d,int i);
void main() {
clrscr();
cout<<"Nhap gia tri cho mang a:\n";
for(int i=0;i<5;i++) {
cout<<"a["<<i<<"]= ";
cin>>fr(a,i);
}
cout<<"Mang a sau khi nhap\n";
for(i=0;i<5;i++)
cout<<a[i]<<" ";
cout<<"\n";
getch();
}
int &fr(int *d,int i) {
return d[i];
}
Nhap gia tri cho mang a:
a[0]= 6
a[1]= 4
a[2]= 3
a[3]= 5
a[4]= 6
Mang a sau khi nhap
6 4 3 5 6
B¹n ®äc cã thÓ xem thªm phÇn “§Þnh nghÜa chång to¸n tö” ®Ó thÊy ®-îc lîi
Ých cña vÊn ®Ò tr¶ vÒ tham chiÕu cho hµm.
§Þnh nghÜa chång hµm (Overloading functions)
6.
C++ cho phÐp sö dông mét tªn cho nhiÒu hµm kh¸c nhau ta gäi ®ã lµ sù
“chång hµm”. Trong tr-êng hîp ®ã, c¸c hµm sÏ kh¸c nhau ë gi¸ trÞ tr¶ vÒ vµ danh
s¸ch kiÓu c¸c tham sè. Ch¼ng h¹n chóng ta muèn ®Þnh nghÜa c¸c hµm tr¶ vÒ sè nhá
nhÊt trong:
-29-
C¸c më réng cña C++
11. hai sè nguyªn
12. hai sè thùc
13. hai ký tù
ba sè nguyªn
14.
15.
mét d·y c¸c sè nguyªn ...
DÜ nhiªn cã thÓ t×m cho mçi hµm nh- vËy mét tªn ph©n. Lîi dông kh¶ n¨ng
“®Þnh nghÜa chång hµm” cña C++, chóng ta cã thÓ viÕt c¸c hµm nh- sau:
VÝ dô 2.12
#include <iostream.h>
//Hµm nguyªn mÉu
int min(int, int); //Hµm 1
double min(double, double);//Hµm 2
char min(char, char);//Hµm 3
int min(int, int, int);//Hµm 4
int min(int, int *);//Hµm 5
main() {
int n=10, p =12, q = -12;
double x = 2.3, y = -1.2;
char c = ‘A’, d= ‘Q’;
int td[7] = {1,3,4,-2,0,23,9};
cout<<“min (n,p) : ”<<min(n,p)<<“\m”; //Hµm 1
cout<<“min (n,p,q) : ”<<min(n,p,q)<<“\m”; //Hµm 4
cout<<“min (c,d) : ”<<min(c,d)<<“\m”; //Hµm 3
cout<<“min (x,y) : ”<<min(n,p)<<“\m”; //Hµm 2
cout<<“min (td) : ”<<min(7,td)<<“\m”; //Hµm 5
cout<<“min (n,x) : ”<<min(n,x)<<“\m”; //Hµm 2
//cout<<“min (n,p,x) : ”<<min(n,p,x)<<“\m”; //Lçi
}
int min(int a, int b) {
return (a> b? a: b);
}
int min(int a, int b, int c) {
-30-
C¸c më réng cña C++
return (min(min(a,b),c));
}
double min(double a, double b) {
return (a> b? a: b);
}
char min(char a, char b) {
return (a> b? a: b);
}
int min(int n, int *t) {
int res = t[0];
for (int i=1; i<n; i++)
res = min(res,t[i]);
return res;
}
NhËn xÐt
Mét hµm cã thÓ gäi ®Õn hµm cïng tªn víi nã (vÝ dô nh- hµm 4,5 gäi hµm 1).
16.
Trong tr-êng hîp cã c¸c hµm trïng tªn trong ch-¬ng tr×nh, viÖc x¸c ®Þnh
hµm nµo ®-îc gäi do ch-¬ng tr×nh dÞch ®¶m nhiÖm vµ tu©n theo c¸c
nguyªn t¾c sau:
17.
Tr-êng hîp c¸c hµm cã mét tham sè
Ch-¬ng tr×nh dÞch t×m kiÕm “sù t-¬ng øng nhiÒu nhÊt” cã thÓ ®-îc; cã c¸c
møc ®é t-¬ng øng nh- sau (theo ®é -u tiªn gi¶m dÇn):
a) T-¬ng øng thËt sù: ta ph©n biÖt c¸c kiÓu d÷ liÖu c¬ së kh¸c nhau ®ång thêi
l-u ý ®Õn c¶ dÊu.
T-¬ng øng d÷ liÖu sè nh-ng cã sù chuyÓn ®æi kiÓu d÷ liÖu tù ®éng
(“numeric promotion”): char vµ short -->int; float -->int.
b)
C¸c chuyÓn ®æi kiÓu chuÈn ®-îc C vµ C++ chÊp nhËn.
c)
d) C¸c chuyÓn ®æi kiÓu do ng-êi sö dông ®Þnh nghÜa.
Qu¸ tr×nh t×m kiÕm b¾t ®Çu tõ møc cao nhÊt vµ dõng l¹i ë møc ®Çu tiªn cho
phÐp t×m thÊy sù phï hîp. NÕu cã nhiÒu hµm phï hîp ë cïng mét møc, ch-¬ng
tr×nh dÞch ®-a ra th«ng b¸o lçi do kh«ng biÕt chän hµm nµo gi÷a c¸c hµm phï hîp.
-31-
C¸c më réng cña C++
Tr-êng hîp c¸c hµm cã nhiÒu tham sè
ý t-ëng chung lµ ph¶i t×m mét hµm phï hîp nhÊt so víi tÊt c¶ nh÷ng hµm cßn
l¹i. §Ó ®¹t môc ®Ých nµy, ch-¬ng tr×nh dÞch chän cho mçi tham sè c¸c hµm phï hîp
(ë tÊt c¶ c¸c møc ®é). Trong sè c¸c hµm ®-îc lùa chän, ch-¬ng tr×nh dÞch chän ra
(nÕu tån t¹i vµ tån t¹i duy nhÊt) hµm sao cho ®èi víi mçi ®èi sè nã ®¹t ®-îc sù phï
hîp h¬n c¶ so víi c¸c hµm kh¸c.
Trong tr-êng hîp vÉn cã nhiÒu hµm tho¶ m·n, lçi biªn dÞch x¶y ra do ch-¬ng
tr×nh dÞch kh«ng biÕt chän hµm nµo trong sè c¸c hµm tháa m·n. §Æc biÖt l-u ý khi
sö dông ®Þnh nghÜa chång hµm cïng víi viÖc khai b¸o c¸c hµm víi tham sè cã gi¸
trÞ ngÇm ®Þnh sÏ ®-îc tr×nh bµy trong môc tiÕp theo.
7. Tham sè ngÇm ®Þnh trong lêi gäi hµm
Ta xÐt vÝ dô sau:
VÝ dô 2.13
#include <iostream.h>
void main() {
int n=10,p=20;
void fct(int, int = 12) ;//khai b¸o hµm víi mét gi¸ trÞ ngÇm ®Þnh
fct(n,p); //lêi gäi th«ng th-êng, cã hai tham sè
fct(n); //lêi gäi chØ víi mét tham sè
//fct() sÏ kh«ng ®-îc chÊp nhËn
}
//khai b¸o b×nh th-êng
void fct(int a, int b) {
cout <<"tham so thu nhat : " <<a <<"\n";
cout<<"tham so thu hai
}
: "<<b<<"\n";
tham so thu nhat : 10
tham so thu hai
tham so thu nhat : 10
tham so thu hai : 12
: 20
Trong khai b¸o cña fct() bªn trong hµm main() :
void fct(int,int =12);
-32-
Tải về để xem bản đầy đủ
Bạn đang xem 20 trang mẫu của tài liệu "Giáo trình Lập trình hướng đối tượng với C++ - Chương 2: Những mở rộng của C++", để tải tài liệu gốc về máy hãy click vào nút Download ở trên
File đính kèm:
giao_trinh_lap_trinh_huong_doi_tuong_voi_c_chuong_2_nhung_mo.pdf

