Để bổ sung các tính năng mới vào C, một số từ khóa (keyword)
mới đã được đưa vào C++ ngoài các từ khóa có trong C.
Các chương trình bằng C nào sử dụng các tên trùng với các từ
khóa cần phải thay đổi trước khi chương trình được dịch lại
bằng C++.
29 trang |
Chia sẻ: lylyngoc | Lượt xem: 1613 | Lượt tải: 2
Bạn đang xem trước 20 trang tài liệu Các mở rộng của C++ so với C, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Lê Thị Mỹ Hạnh
Khoa CNTT
Đại học Bách khoa – Đại học Đà Nẵng
Từ khóa
Để bổ sung các tính năng mới vào C, một số từ khóa (keyword)
mới đã được đưa vào C++ ngoài các từ khóa có trong C.
Các chương trình bằng C nào sử dụng các tên trùng với các từ
khóa cần phải thay đổi trước khi chương trình được dịch lại
bằng C++.
Các từ khóa mới này là :
asm catch class delete friend inline
new operator private protected public
template this throw try virtual
Chú thích
chó thÝch trong C b»ng /* ... */
C++ ®-a thªm chó thÝch b¾t ®Çu b»ng //.
kiÓu chó thÝch /*...*/ ®-îc dïng cho c¸c khèi chó thÝch lín
gåm nhiÒu dßng,
cßn kiÓu // ®-îc dïng cho c¸c chó thÝch trªn mét dßng.
VÝ dô: /* §©y lµ
chó thÝch trong C */
// §©y lµ chó thÝch trong C++
Khai báo biến
Trong C tÊt c¶ c¸c c©u lÖnh khai b¸o biÕn, m¶ng côc bé
ph¶i ®Æt t¹i ®Çu khèi.
vÞ trÝ khai b¸o vµ vÞ trÝ sö dông cña biÕn cã thÓ ë c¸ch kh¸ xa
nhau, ®iÒu nµy g©y khã kh¨n trong viÖc kiÓm so¸t ch-¬ng
tr×nh.
C++ ®· kh¾c phôc nh-îc ®iÓm nµy b»ng c¸ch cho phÐp
c¸c lÖnh khai b¸o biÕn cã thÓ ®Æt bÊt kú chç nµo trong
ch-¬ng tr×nh tr-íc khi c¸c biÕn ®-îc sö dông.
Ph¹m vi ho¹t ®éng cña c¸c biÕn kiÓu nµy lµ khèi trong ®ã
biÕn ®-îc khai b¸o.
Phép chuyển kiểu
Trong C phÐp chuyÓn kiÓu ®-îc viÕt theo có ph¸p:
(kiÓu) biÓu thøc
C++ cßn sö dông mét phÐp chuyÓn kiÓu míi:
KiÓu(biÓu thøc)
PhÐp chuyÓn kiÓu nµy cã d¹ng nh- mét hµm sè chuyÓn
kiÓu ®ang ®-îc gäi. C¸ch chuyÓn kiÓu nµy th-êng ®-îc sö
dông trong thùc tÕ.
Vào ra trong C++
XuÊt d÷ liÖu
Có ph¸p: cout << biÓu thøc 1<<. . .<< biÓu thøc N;
Trong ®ã cout ®-îc ®Þnh nghÜa tr-íc nh- mét ®èi t-îng biÓu diÔn cho thiÕt
bÞ xuÊt chuÈn cña C++ lµ mµn h×nh, cout ®-îc sö dông kÕt hîp víi to¸n tö
chÌn << ®Ó hiÓn thÞ gi¸ trÞ c¸c biÓu thøc 1, 2,..., N ra mµn h×nh.
NhËp d÷ liÖu
Có ph¸p: cin >>biÕn 1>>. . . >>biÕn N;
To¸n tö cin ®-îc ®Þnh nghÜa tr-íc nh- mét ®èi t-îng biÓu diÔn cho thiÕt bÞ
vµo chuÈn cña C++ lµ bµn phÝm, cin ®-îc sö dông kÕt hîp víi to¸n tö trÝch
>> ®Ó nhËp d÷ liÖu tõ bµn phÝm cho c¸c biÕn 1, 2, ..., N.
Chó ý:
§Ó nhËp mét chuçi kh«ng qu¸ n ký tù vµ l-u vµo m¶ng mét chiÒu a (kiÓu
char) cã thÓ dïng hµm cin.get nh- sau: cin.get(a,n);
To¸n tö nhËp cin>> sÏ ®Ó l¹i ký tù chuyÓn dßng ’\n’ trong bé ®Öm. Ký tù nµy
cã thÓ lµm tr«i ph-¬ng thøc cin.get. §Ó kh¾c phôc t×nh tr¹ng trªn cÇn dïng
ph-¬ng thøc cin.ignore(1) ®Ó bá qua mét ký tù chuyÓn dßng.
§Ó sö dông c¸c lo¹i to¸n tö vµ ph-¬ng thøc nãi trªn cÇn khai b¸o tËp tin dÉn
h-íng iostream.h
Vào ra trong C++ (2)
§Þnh d¹ng khi in ra mµn h×nh
§Ó quy ®Þnh sè thùc ®-îc hiÓn thÞ ra mµn h×nh víi p ch÷ sè sau dÊu chÊm
thËp ph©n, ta sö dông ®ång thêi c¸c hµm sau:
setiosflags(ios::showpoint);//Bật cờ hiệu showpoint(p)
setprecision(p);
C¸c hµm nµy cÇn ®Æt trong to¸n tö xuÊt nh- sau:
cout<<setiosflags(ios::showpoint)<<setprecision(p);
C©u lÖnh trªn sÏ cã hiÖu lùc ®èi víi tÊt c¶ c¸c to¸n tö xuÊt tiÕp theo cho ®Õn
khi gÆp mét c©u lÖnh ®Þnh d¹ng míi.
§Ó quy ®Þnh ®é réng tèi thiÓu ®Ó hiÓn thÞ lµ k vÞ trÝ cho gi¸ trÞ (nguyªn, thùc,
chuçi) ta dïng hµm: setw(k)
Hµm nµy cÇn ®Æt trong to¸n tö xuÊt vµ nã chØ cã hiÖu lùc cho mét gi¸ trÞ ®-îc
in gÇn nhÊt. C¸c gi¸ trÞ in ra tiÕp theo sÏ cã ®é réng tèi thiÓu mÆc ®Þnh lµ 0,
nh- vËy c©u lÖnh:
cout<<setw(6)<<“Khoa”<<“CNTT”
sÏ in ra chuçi “ KhoaCNTT”.
Toán tử định phạm vi (::)
Toán tử định phạm vi (scope resolution operator) ký hiệu là ::,
nó được dùng truy xuất một phần tử bị che bởi phạm vi hiện
thời.
Ví dụ:
#include
int X = 5;
int main() {
int X = 16;
cout<< "Bien X ben trong = "<<X<<"\n";
cout<< "Bien X ben ngoai = "<<::X<<"\n";
return 0;
}
Cấp phát và giải phóng bộ nhớ
Trong C để cÊp ph¸t bé nhí dïng: malloc(), calloc() vµ ®Ó
gi¶i phãng bé nhí ®-îc cÊp ph¸t dïng hµm free().
C++ ®-a thªm mét c¸ch thøc míi ®Ó thùc hiÖn viÖc cÊp
ph¸t vµ gi¶i phãng bé nhí b»ng c¸ch dïng hai to¸n tö new
vµ delete.
Cấp phát và giải phóng bộ nhớ
To¸n tö new ®Ó cÊp ph¸t bé nhí
new Tªn kiÓu ;
hoÆc new Tªn kiÓu(Gi¸ trÞ khëi t¹o);
Trong ®ã Tªn kiÓu lµ kiÓu d÷ liÖu cña biÕn con trá, nã cã thÓ lµ: c¸c kiÓu d÷ liÖu chuÈn nh- int, float,
double, char,... hoÆc c¸c kiÓu do ng-êi lËp tr×nh ®Þnh nghÜa nh- m¶ng, cÊu tróc, líp,...
§Ó cÊp ph¸t bé nhí cho m¶ng mét chiÒu, dïng có ph¸p nh- sau:
BiÕn con trá = new kiÓu[n];
Trong ®ã n lµ sè nguyªn d-¬ng x¸c ®Þnh sè phÇn tö cña m¶ng.
VÝ dô: float *p = new float; //cÊp ph¸t bé nhí cho biÕn con trá p cã kiÓu int
int *a = new int[100]; //cÊp ph¸t bé nhí ®Ó l-u tr÷ m¶ng mét chiÒu a gåm 100 phÇn tö
Khi sö dông to¸n tö new ®Ó cÊp ph¸t bé nhí, nÕu kh«ng ®ñ bé nhí ®Ó cÊp ph¸t, new sÏ tr¶ l¹i
gi¸ trÞ NULL cho con trá. §o¹n ch-¬ng tr×nh sau minh häa c¸ch kiÓm tra lçi cÊp ph¸t bé nhí:
double *p;
int n;
cout<< “\n So phan tu : ”;
cin>>n;
p = new double[n]
if (p == NULL)
{
cout << “Loi cap phat bo nho”;
exit(0);
}
Cấp phát và giải phóng bộ nhớ
To¸n tö delete ®Ó gi¶i phãng bé nhí
To¸n tö delete thay cho hµm free() cña C, nã cã có ph¸p nh-
sau:
delete contrá ;
§Ó gi¶i phãng vïng nhí ®· cÊp ph¸t cho m¶ng
delete [ ] contrá;
VÝ dô: Thu håi vïng nhí ®· cÊp ph¸t cho hai biÕn con trá p
vµ a (víi a lµ mét m¶ng mét chiÒu)
delete p;
delete [ ] a;
Hàm inline
ViÖc tæ chøc ch-¬ng tr×nh thµnh c¸c hµm cã -u ®iÓm ch-¬ng tr×nh
®-îc chia thµnh c¸c ®¬n vÞ ®éc lËp, ®iÒu nµy gi¶m ®-îc kÝch th-íc
ch-¬ng tr×nh, v× mçi ®o¹n ch-ong tr×nh thùc hiÖn nhiÖm vô cña hµm
®-îc thay b»ng lêi gäi hµm.
Tuy nhiªn hµm còng cã nh-îc ®iÓm lµ lµm lµ chËm tèc ®é thùc hiÖn
ch-¬ng tr×nh v× ph¶i thùc hiÖn mét sè thao t¸c cã tÝnh thñ tôc mçi khi
gäi hµm nh-: cÊp ph¸t vïng nhí cho c¸c ®èi sè vµ biÕn côc bé,
truyÒn d÷ liÖu cña c¸c tham sè cho c¸c ®èi, gi¶i phãng vïng nhí
tr-íc khi tho¸t khái hµm.
C++ cho kh¶ n¨ng kh¾c phôc ®-îc nh-îc ®iÓm nãi trªn b»ng c¸ch
dïng hµm néi tuyÕn. §Ó biÕn mét hµm thµnh hµm néi tuyÕn ta viÕt
thªm tõ khãa inline vµo tr-íc khai b¸o nguyªn mÉu hµm.
Chó ý:
Trong mäi tr-êng hîp, tõ khãa inline ph¶i xuÊt hiÖn tr-íc c¸c lêi gäi
hµm th× tr×nh biªn dÞch míi biÕt cÇn xö lý hµm theo kiÓu inline.
ChØ nªn khai b¸o lµ hµm inline khi hµm cã néi dung ®¬n gi¶n.
Hµm ®Ö qui kh«ng thÓ lµ hµm inline.
Hàm inline - Ví dụ
#include
#include
inline int f(int a,int b);
void main()
{
int s ;
s=f(5,6);
cout<<s;
getch();
}
int f(int a,int b)
{
return a*b;
}
#include
#include
inline int f(int a,int b)
{
return a*b;
}
void main()
{
int s ;
s=f(5,6);
cout<<s;
getch();
}
Biến tham chiếu
Trong C cã 2 lo¹i biÕn lµ:
BiÕn gi¸ trÞ dïng ®Ó chøa d÷ liÖu (nguyªn, thùc, ký tù,...) và biÕn con trá
dïng ®Ó chøa ®Þa chØ.
C¸c biÕn nµy ®Òu ®-îc cung cÊp bé nhí vµ cã ®Þa chØ.
C++ cho phÐp sö dông lo¹i biÕn thø ba lµ biÕn tham chiÕu.
BiÕn tham chiÕu lµ mét tªn kh¸c (bÝ danh) cho biÕn ®· ®Þnh nghÜa tr-íc
®ã.
Có ph¸p khai b¸o biÕn tham chiÕu nh- sau:
KiÓu &BiÕn tham chiÕu = BiÕnHằng;
BiÕn tham chiÕu cã ®Æc ®iÓm lµ nã ®-îc dïng lµm bÝ danh cho mét biÕn
(kiÓu gi¸ trÞ) nµo ®ã vµ sö dông vïng nhí cña biÕn nµy.
Biến tham chiếu
VÝ dô: Víi c©u lÖnh: int a, &tong=a; th× tong lµ bÝ danh cña biÕn a vµ biÕn tong dïng
chung vïng nhí cña biÕn a. Lóc nµy, trong mäi c©u lÖnh, viÕt a hay viÕt tong ®Òu cã ý
nghÜa nh- nhau, v× ®Òu truy nhËp ®Õn cïng mét vïng nhí. Mäi sù thay ®æi ®èi víi biÕn
tong ®Òu ¶nh h-ëng ®èi víi biÕn a vµ ng-îc l¹i.
VÝ dô: int a, &tong =a;
tong =1; //a=1
cout<< tong; //in ra sè 1
tong++; //a=2
++a; //a=3
cout<<tong; //in ra sè 3
Chó ý:
Trong khai b¸o biÕn tham chiÕu ph¶i chØ râ tham chiÕu ®Õn biÕn nµo.
BiÕn tham chiÕu cã thÓ tham chiÕu ®Õn mét phÇn tö m¶ng, nh-ng kh«ng cho phÐp khai b¸o
m¶ng tham chiÕu.
BiÕn tham chiÕu cã thÓ tham chiÕu ®Õn mét h»ng. Khi ®ã nã sö dông vïng nhí cña h»ng vµ cã
thÓ lµm thay ®æi gi¸ trÞ chøa trong vïng nhí nµy.
BiÕn tham chiÕu th-êng ®-îc sö dông lµm ®èi cña hµm ®Ó cho phÐp hµm truy nhËp ®Õn c¸c
tham biÕn trong lêi gäi hµm
Hằng tham chiếu
Có ph¸p khai b¸o h»ng tham chiÕu nh- sau:
const KiÓu d÷ liÖu &Hằng = BiÕn/H»ng;
VÝ dô: int n = 10;
const int &m = n;
const int &p = 123;
H»ng tham chiÕu cã thÓ tham chiÕu ®Õn mét biÕn hoÆc mét h»ng.
Chó ý:
BiÕn tham chiÕu vµ h»ng tham chiÕu kh¸c nhau ë chç: kh«ng cho phÐp dïng h»ng tham
chiÕu ®Ó lµm thay ®æi gi¸ trÞ cña vïng nhí mµ nã tham chiÕu.
VÝ dô: int y=12, z;
const int &p = y //H»ng tham chiÕu p tham chiÕu ®Õn biÕn y
p = p + 1; //Sai, tr×nh biªn dÞch sÏ th«ng b¸o lçi
H»ng tham chiÕu cho phÐp sö dông gi¸ trÞ chøa trong mét vïng nhí, nh-ng kh«ng cho
phÐp thay ®æi gi¸ trÞ nµy.
H»ng tham chiÕu th-êng ®-îc sö dông lµm ®èi sè cña hµm ®Ó cho phÐp sö dông gi¸ trÞ cña
c¸c tham sè trong lêi gäi hµm, nh-ng tr¸nh lµm thay ®æi gi¸ trÞ tham sè.
Truyền tham số cho hàm theo tham chiếu
Trong C chØ cã mét c¸ch truyÒn d÷ liÖu cho hµm lµ truyÒn theo
theo gi¸ trÞ.
Ch-¬ng tr×nh sÏ t¹o ra c¸c b¶n sao cña c¸c tham sè thùc sù trong
lêi gäi hµm vµ sÏ thao t¸c trªn c¸c b¶n sao nµy chø kh«ng xö lý
trùc tiÕp víi c¸c tham sè thùc sù.
C¬ chÕ nµy rÊt tèt nÕu khi thùc hiÖn hµm trong ch-¬ng tr×nh
kh«ng cÇn lµm thay ®æi gi¸ trÞ cña biÕn gèc.
Tuy nhiªn, nhiÒu khi ta l¹i muèn nh÷ng tham sè ®ã thay ®æi khi
thùc hiÖn hµm trong ch-¬ng tr×nh.
C++ cung cÊp thªm c¸ch truyÒn d÷ liÖu cho hµm theo tham
chiÕu b»ng c¸ch dïng ®èi lµ tham chiÕu.
C¸ch lµm nµy cã -u diÓm lµ kh«ng cÇn t¹o ra c¸c b¶n sao cña c¸c
tham sè, do dã tiÕt kiÖm bé nhí vµ thêi gian ch¹y m¸y.
MÆt kh¸c, hµm nµy sÏ thao t¸c trùc tiÕp trªn vïng nhí cña c¸c
tham sè, do ®ã dÔ dµng thay ®æi gi¸ trÞ c¸c tham sè khi cÇn.
Truyền tham số theo tham chiếu – Ví dụ
void Hoanvi(double &x,double &y)
{
double tam = x; x = y; y = tam;
}
void sapxep(double *a,int n)
{
for(int i=0;i<n-1;++i)
for(int j=i+1;j<n;++j)
if(a[i]>a[j])
Hoanvi(a[i],a[j]);
}
Hàm trả về là một tham chiếu
C++ cho phÐp hµm tr¶ vÒ gi¸ trÞ lµ mét tham chiÕu, lóc nµy ®Þnh nghÜa cña hµm cã
d¹ng nh- sau :
KiÓu &Tªn hµm(...) {
//th©n hµm
return ;
}
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× 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. Do vËy tham chiÕu cña hµm sÏ kh«ng
cßn ý nghÜa n÷a. V× vËy, nÕu hµm tr¶ vÒ lµ tham chiÕu ®Õn biÕn côc bé th× biÕn côc
bé nµy ph¶i khai b¸o static.
VÝ dô:
int &myfunc(){
static int x= 10;
return x;
}
Hàm trả về là một tham chiếu
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 h¬i kh¸c th-êng, 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.
VÝ dô:
#include
int X = 4;
int & MyFunc();
int main() {
cout<<"X="<<X<<endl;
cout<<"X="<<MyFunc()<<endl;
MyFunc() = 20; //Nghĩa là X = 20
cout<<"X="<<X<<endl;
return 0;
}
int & MyFunc() {
return X;
}
=> Kết quả ?
Hàm với đối số mặc đinh
Một trong các đặc tính nổi bật nhất của C++ là khả năng định nghĩa các giá
trị tham số mặc định cho các hàm.
Bình thường khi gọi một hàm, chúng ta cần gởi một giá trị cho mỗi tham số
đã được định nghĩa trong hàm đó, chẳng hạn chúng ta có đoạn chương trình
sau:
void MyDelay(long Loops); //prototype
Mỗi khi hàm MyDelay() được gọi chúng ta phải gởi cho nó một giá trị cho
tham số Loops.
Tuy nhiên, trong nhiều trường hợp chúng ta có thể nhận thấy rằng chúng ta
luôn luôn gọi hàm MyDelay() với cùng một giá trị Loops nào đó. Muốn vậy
chúng ta sẽ dùng giá trị mặc định cho tham số Loops, giả sử chúng ta muốn
giá trị mặc định cho tham số Loops là 1000.
Khi đó đoạn mã trên được viết lại như sau :
void MyDelay(long Loops = 1000); //prototype
Mỗi khi gọi hàm MyDelay() mà không gởi một tham số tương ứng thì trình
biên dịch sẽ tự động gán cho tham số Loops giá trị 1000.
MyDelay(); // Loops có giá trị là 1000
MyDelay(5000); // Loops có giá trị là 5000
Hàm với đối số mặc định
Quy t¾c x©y dùng hµm víi ®èi sè mÆc ®Þnh nh- sau:
C¸c ®èi cã gi¸ trÞ mÆc ®Þnh cÇn lµ c¸c ®èi sè cuèi cïng tÝnh tõ tr¸i qua ph¶i.
int MyFunc(int a=1, int b, int c=3, int d=4); //prototype sai!!!
int MyFunc(int a, int b=2, int c=3, int d=4); //prototype đúng
NÕu ch-¬ng tr×nh sö dông khai b¸o nguyªn mÉu hµm th× c¸c ®èi sè mÆc ®Þnh
cÇn ®-îc khëi g¸n trong nguyªn mÉu hµm, kh«ng ®-îc khëi g¸n khëi g¸n l¹i
cho c¸c ®èi mÆc ®Þnh trong dßng ®Çu cña ®Þnh nghÜa hµm.
Khi x©y dùng hµm, nÕu kh«ng khai b¸o nguyªn mÉu, th× c¸c ®èi mÆc ®Þnh
®-îc khëi g¸n trong dßng ®Çu cña ®Þnh nghÜa hµm.
§èi víi c¸c hµm cã ®èi sè mÆc ®Þnh th× lêi gäi hµm cÇn viÕt theo quy ®Þnh: C¸c
tham sè v¾ng mÆt trong lêi gäi hµm t-¬ng øng víi c¸c ®èi sè mÆc ®Þnh cuèi
cïng (tÝnh tõ tr¸i sang ph¶i),
MyFunc(); // Lỗi do tham số a không có giá trị mặc định
MyFunc(1);// OK, các tham số b, c và d lấy giá trị mặc định
MyFunc(5, 7); // OK, các tham số c và d lấy giá trị mặc định
MyFunc(5, 7, , 8); // Lỗi do các tham số bị bỏ phải liên tiếp nhau
Đa năng hóa (Overloading)
Với ngôn ngữ C++, chúng ta có thể đa năng hóa các hàm
và các toán tử (operator).
Đa năng hóa là phương pháp cung cấp nhiều hơn một định
nghĩa cho tên hàm đã cho trong cùng một phạm vi.
Trình biên dịch sẽ lựa chọn phiên bản thích hợp của hàm
hay toán tử dựa trên các tham số mà nó được gọi.
Có hai hình thức đa năng hóa:
Đa năng hóa hàm
Đa năng hóa toán tử
Đa năng hóa hàm(Function Overloading)
Trong ngôn ngữ C cũng như mọi ngôn ngữ máy tính khác, mỗi hàm đều
phải có một tên phân biệt.
Như trong ngôn ngữ C, có rất nhiều hàm trả về trị tuyệt đối của một tham số là
số, vì cần thiết phải có tên phân biệt nên C phải có hàm riêng cho mỗi kiểu dữ
liệu số,
do vậy có tới ba hàm khác nhau để trả về trị tuyệt đối của một tham số :
int abs(int i);
long labs(long l);
double fabs(double d);
Tất cả các hàm này đều cùng thực hiện một chứa năng nên chúng ta thấy điều
này nghịch lý khi phải có ba tên khác nhau.
C++ giải quyết điều này bằng cách cho phép chúng ta tạo ra các hàm khác
nhau có cùng một tên. Đây chính là đa năng hóa hàm.
Như vậy, trong C++ chúng ta có thể định nghĩa lại các hàm trả về trị tuyệt
đối để thay thế các hàm trên như sau :
int Myabs(int i);
long Myabs(long l);
double Myabs(double d);
Đa năng hóa hàm(Function Overloading)
Trình biên dịch dựa vào sự khác nhau về số các tham số, kiểu
của các tham số để có thể xác định chính xác phiên bản cài
đặt nào của hàm MyAbs() thích hợp với một lệnh gọi hàm
được cho,
MyAbs(-7); //Gọi hàm int MyAbs(int)
MyAbs(-7l); //Gọi hàm long MyAbs(long)
MyAbs(-7.5); //Gọi hàm double MyAbs(double)
Quá trình tìm hàm đa năng hóa :
nếu tìm thấy một phiên bản định nghĩa nào đó của một hàm được
đa năng hóa mà có kiểu dữ liệu các tham số của nó trùng với
kiểu các tham số đã gởi tới trong lệnh gọi hàm thì phiên bản hàm
đó sẽ được gọi.
Nếu không trình biên dịch C++ sẽ gọi đến phiên bản nào cho
phép chuyển kiểu dễ dàng nhất.
MyAbs(„c‟); //Gọi int MyAbs(int)
MyAbs(2.34f); //Gọi double MyAbs(double)
Bất kỳ hai hàm nào trong tập các hàm đã đa năng phải có
các tham số khác nhau.
Đa năng hóa toán tử (Operators overloading)
Trong C, khi tạo ra một kiểu dữ liệu mới, để thực hiện các thao
tác liên quan đến kiểu dữ liệu đó thường thông qua các hàm
Ví dụ:
typedef struct Complex{
double Real;
double Imaginary;
};
Complex SetComplex(double R,double I);
Complex AddComplex(Complex C1,Complex C2);
Complex SubComplex(Complex C1,Complex C2);
=> C3 = AddComplex(C1,C2); //Hơi bất tiện !!!
C4 = SubComplex(C1,C2);
Điều này trở nên không thoải mái vì thực chất thao tác cộng và
trừ là các toán tử chứ không phải là hàm.
Đa năng hóa toán tử (Operators overloading)
Để khắc phục yếu điểm này, trong C++ cho phép chúng ta có thể
định nghĩa lại chức năng của các toán tử đã có sẵn một cách tiện lợi
và tự nhiên hơn rất nhiều.
Điều này gọi là đa năng hóa toán tử..
Ví dụ:
Complex operator + (Complex C1,Complex C2);
Complex operator - (Complex C1,Complex C2);
=> C3 = C1 + C2;
C4 = C1 - C2;
Như vậy trong C++, các phép toán trên các giá trị kiểu số phức được
thực hiện bằng các toán tử toán học chuẩn chứ không phải bằng các
tên hàm như trong C.
Chẳng hạn chúng ta có lệnh sau:
C4 = AddComplex(C3, SubComplex(C1,C2));
thì ở trong C++, chúng ta có lệnh tương ứng như sau:
C4 = C3 + C1 - C2;
Đa năng hóa toán tử (Operators overloading)
Cú pháp:
data_type operator oper_sym( parameters ){
………………………………
}
Trong đó:
data_type: Kiểu trả về.
operator_symbol: Ký hiệu của toán tử.
parameters: Các tham số (nếu có).
Các toán tử được đa năng hóa sẽ được lựa chọn bởi trình
biên dịch:
khi gặp một toán tử làm việc trên các kiểu không phải là kiểu
có sẵn, trình biên dịch sẽ tìm một hàm định nghĩa của toán tử
nào đó có các tham số đối sánh với các toán hạng để dùng.
Đa năng hóa toán tử (Operators overloading)
Các giới hạn của đa năng hóa toán tử:
Chúng ta không thể định nghĩa các toán tử mới.
Hầu hết các toán tử của C++ đều có thể được đa năng hóa.
Các toán tử sau không được đa năng hóa là :
:: Toán tử định phạm vi.
.* Truy cập đến con trỏ là trường của struct hay thành viên của class.
. Truy cập đến trường của struct hay thành viên của class.
?: Toán tử điều kiện
sizeof
và chúng ta cũng không thể đa năng hóa bất kỳ ký hiệu tiền xử lý nào.
Chúng ta không thể thay đổi thứ tự ưu tiên của một toán tử hay không thể thay đổi số các toán
hạng của nó.
Chúng ta không thể thay đổi ý nghĩa của các toán tử khi áp dụng cho các kiểu có sẵn.
Đa năng hóa các toán tử không thể có các tham số có giá trị mặc định.
Các toán tử có thể đa năng hoá:
+ - * / % ^ ! = += -=
^= &= |= > = && || ++ --
() [] new delete & | ~ *= /= %= >>= == != , -> ->*