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

Tài liệu OPP C++ (phần 2) docx

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 (704.82 KB, 20 trang )


1
1
1
1
1
1
1
2



Chúng
t
Chú
1
3:
1
4: ret
1
5: }

1
6: //Tín
h
1
7: int Bo
1
8: {

1


9: ret
2
0: }

t
a chạy ví d

ý:
Các tham
được lặp lạ
i
prototype c
h
Một hàm
c
định cần ph
Khi gọi hà
m
số theo thứ
t
chương trìn
h
int
M
int
M


My
F

<< BoxVol
u
urn 0;

h
thể tích
xVolume(i
n
urn Lengt
h


2.11, kết
q
số có giá tr

i
trong định
n
h
ứ không p
h
c
ó thể có n
h
ải được nhó
m
m
có nhiều t
h

t
ự từ phải s
a
h
như sau:
M
yFunc(int
a
M
yFunc(int
a

…………

F
unc(); // L

u
me(10, 5,
của h
ì
nh
n
t Length,
h
* Width
q
uả ở hình 2.
Hình 2.1
3


mặc định c
h
n
ghĩa hàm (
V
h
ải trong địn
h
h
iều tham số
m
lại vào c
á
h
am số có g
i
a
ng trái và p
h
a
= 1, int b ,
i
a
, int b = 2 ,

……
i do tham s

31

2)<< end
l
hộp

int Widt
h
* Height;
13
3
: Kết quả c

h
ỉ được cho
V
ì trình biê
n
h
nghĩa hà
m
có giá trị m

á
c tham số c
u
i
á trị mặc đị
n
h
ải bỏ liên t
i

i
nt c = 3, in
t
int c = 3, in

a không c
ó
l
;
h
, int Hei
g

a ví dụ 2.1
1
trong proto
t
n
dịch sẽ dù
n
m
để tạo một

c định. Cá
c
u
ối cùng (h
o
n
h, chúng ta

i
ếp nhau, ch
t
d = 4); //pr
o
t d = 4); //p
r
ó
giá trị mặc
g
ht)


1

t
ype của hà
m
n
g các thôn
g
lệnh gọi).
c
tham số có
o
ặc duy nhất
)
chỉ có thể
b
ẳng hạn ch

ú
o
totype sai!!
r
ototype đú
n
định
m
và không
g
tin trong
giá trị mặc
)
của một h
à
b
ỏ bớt các th
ú
ng ta có đo

!
n
g

à
m.
am

n
32


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
2.2.12 Phép tham chiếu

Trong C, hàm nhận tham số là con trỏ đòi hỏi chúng ta phải thận trọng khi gọi hàm. Chúng ta cần
viết hàm hoán đổi giá trị giữa hai số như sau:
void Swap(int *X, int *Y);
{
int Temp = *X;
*X = *Y;
*Y = *Temp;
}
Để hoán đổi giá trị hai biến A và B thì chúng ta gọi hàm như sau:
Swap(&A, &B);
Rõ ràng cách viết này không được thuận tiện lắm. Trong trường hợp này, C++ đưa ra một kiểu biến
rất đặc biệt gọi là biến tham chiếu (reference variable). Một biến tham chiếu giống như
là một bí
danh của biến khác. Biến tham chiếu sẽ làm cho các hàm có thay đổi nội dung các tham số của nó
được viết một cách thanh thoát hơn. Khi đó hàm Swap() được viết như sau:
void Swap(int &X, int &Y);
{
int Temp = X;
X = Y;
Y = Temp ;
}
Chúng ta gọi hàm như sau :
Swap(A, B);
Với cách gọi hàm này, C++ tự gởi địa chỉ của A và B làm tham số cho hàm Swap(). Cách dùng biến

tham chiếu cho tham số của C++ tương tự như các tham số được khai báo là Var trong ngôn ngữ

Pascal.
chiếu c
ó
data_t
yp
Trong
đ
Khi dù
n
cấu trú
c
tượng l

Hình 2
.
Ví dụ
2

1
2
3
4
5
6
7
8
Tham số n
à

ó
cú pháp n
h
yp
e

&

varia
b
đ
ó:
data_type
:
K
variable_n
a
n
g biến tha
m
c
hay đối tư


n cho một
h
.
14: Một th
a
2

.12: Chươn
g
1
: #inclu
d
2
: //proto
3
void Sw
a
4
:

5
: int mai
6
: {

7
: i
n
8
: co
à
y được gọi
l
h
ư sau :
b
le_name

;
K
iểu dữ liệu
a
me
: Tên củ
a
m
chiếu cho
t

ng đó như
h
h
àm.
a
m số kiểu t
h
g
trình hoán
d
e <iostre
a
type

a
p(int &X,
i
n()


n
t X = 10,
ut<<"Truo
c
l
à tham số k
i
của biến.
a
biến
t
ham số chỉ
h
ình 2.14, đ
i
h
am chiếu n
h
đổi giá trị c

C
a
m.h>
i
nt &Y);

Y = 5;

c
khi hoan

33
i
ểu tham ch
i
có địa chỉ c

i
ều này rất
h
h
ận một tha
m
của hàm
.

a hai biến.
C
T2_12.CPP
doi: X =
i
ếu (referen
c

a nó được
g
h
ữu dụng kh
i
m
chiếu tới

m
.

"<<X<<",Y
c
e paramete
r
g
ởi đi chứ k
h
i
chúng ta g

m
ột biến đư

= "<<Y<<
e
r
). Như vậy
b
h
ông phải là

i cấu trúc v

c chuyển c
h
e
ndl;


b
iến tham
toàn bộ
à đối
h
o tham số

9
1
1
1
1
1
1
1
1
1
1



Chúng
t
Đôi kh
i
không
m
int My
F

Hàm
M
không
t
giản n
h
int Co
u
int &
R
++Ref;
Các bi
ế
lại một
int X =
int &
Y
Khi m

danh c
h
9
: S
w
1
0: co
1
1: re
1
2: }


1
3:

1
4: void S
1
5: {

1
6: i
n
1
7: X
=
1
8: Y
=
1
9: }

t
a chạy ví d

i
chúng ta
m
m
uốn giá trị
F

unc(const i
n
M
yFunc()
sẽ
c
t
hể bị thay
đ
h
ư một tên k
h
u
nt = 1;
R
ef = Count;
//Tăng biến
ế
n tham chiế
u
bí danh của
1;
Y
; //Lỗi: Y p
h

t tham chiế
u
h
ính là thực

h
w
ap(X,Y);

ut<<"Sau
k
turn 0;

wap(int &
X
n
t Temp=X;

=
Y;

=
Temp;



2.12, kết
q
m
uốn gởi mộ
t
của nó bị t
h
n
t & X);

c
hấp nhận
m
đ
ổi.Biến tha
m
h
ác của biế
n

//Tạo biến
R
Count lên
1
u
phải được
biến khác c
h
ải được kh

u
được khai
b
h
iện trên bi
ế
k
hi hoan
d
X

,int &Y)

q
uả ở hình 2.
Hình 2.1
5
t
tham số nà
o
h
ay đổi thì c
h

m
ột tham số
X
m
chiếu có t
h
n
gốc), chẳn
g

R
ef như là
m
1
(sử dụng b
í
khởi động

t
ho chúng.
C

i động.
b
áo như mộ
ế
n gốc của n
34
d
oi: X = "
<
15
5
: Kết quả c

o
đó bằng b
i
h
úng ta dùn
g

X

gởi bằng t
h
h
ể sử dụng

n
g
hạn như đ
o

m
ột bí danh
c
í
danh của b
t
rong phần
k
C
hẳng hạn đ
o
t bí danh củ
a
n
ó. Chúng ta
<
<X<<",Y =

a ví dụ 2.1
2
i
ến tham ch
i
g
thêm từ k

h

h
am chiếu
n
n
hư một bí
d
o
ạn mã sau :

c
ủa biến Co
u
iến Count)
k
hai báo của
o
ạn
m
ã sau l
a
biến khác,
có thể lấy đ
"<<Y<<en
d

2

i

ếu cho hiệu
h
óa
const
nh
ư

n
hưng
const

d
anh của biế
n


u
nt

chúng và c
h
à sai:
mọi thao tá
c
ịa chỉ của b
i
d
l;



quả, mặc d
ù
ư
sau :

xác định rằ
n
n
khác (bí d
a




h
úng ta khô
n
c
thực hiện
t
i
ến tham chi

ù
chúng ta


n
g
X

a
nh đơn




n
g thể gán
tr
ên bí
ếu và có





thể so
s
Ví dụ
2

1
2
3
4
5
6
7
8
9

1
1
1
1
1



Chúng
t
Ví dụ
2

s
ánh các biế
n
2
.13: Mọi th
a
1
: #inclu
d
2
: int mai
3
: {

4
: int
5

: int
6
: int
7
:

8
: cout
9
: Y *
=
1
0: cout
1
1: Y =
1
2: cout
1
3: ret
u
1
4: }

t
a chạy ví d

2
.14: Lấy đị
a
n

tham chiế
u
a
o tác t
r
ên t
r
d
e <iostre
a
n()

X = 3;

&Y = X; /
/
Z = 100;

<<"X="<<X
<
=
3;

<<"X="<<X
<
Z;

<<"X="<<X
<
u

rn 0;



2.13, kết
q
a
chỉ của biế
n
u
với nhau (
p
r
ên bí danh
c
C
a
m.h>
/
Y la bí
d
<
<endl<<"Y
<
<endl<<"Y
<
<endl<<"Y
q
uả ở hình 2.
Hình 2.1

6
n
tham chiế
u
C
35
p
hải tương t
h
c
hính là tha
o
C
T2_13.CPP
d
anh của X
="<<Y<<en
d
="<<Y<<en
d
="<<Y<<en
d
16
6
: Kết quả c

u

C
T2_14.CPP

h
ích về kiểu
o
tác trên biế
d
l;

d
l;

d
l;


a ví dụ 2.1
3
tham chiếu
)
n gốc của n
ó

3

)
.
ó
.






1
2
3
4
5
6
7
8
9
1



Chúng
t
Chúng
t
:int &
R
Trong
t
chính l
à
Các hà
m
tới một
khi hà
m

Khi m

Ví dụ
2
1
: #inclu
d
2
: int mai
3
: {

4
: int
5
: int
6
:

7
: cout
8
: cout
9
: ret
u
1
0: }

t

a chạy ví d

t
a có thể tạ
o
R
ef = 45;
t
r
ư
ờng hợp
n
à
bí danh củ
a
m
có thể trả
biến cục b

m
kết thúc bi
int & MyF
u
{
static int X
=
return X;
}

t hàm trả v


2
.15:
d
e <iostre
a
n()

X = 3;

&Y = X; /
/
<<"Dia ch
i
<<"Dia ch
i
u
rn 0;



2.14, kết
q
o
ra biến tha
m

n
ày, trình bi
ê

a
biến tạm t
h
về một tha
m

của hàm th
ì
ến cục bộ n
à
u
nc()
=
200; //Nế
u

một tham
c
a
m.h>
/
Y la bí
d
i
cua X =
i
cua bi
d
q
uả ở hình 2.

Hình 2.1
7
m
chiếu với

ê
n dịch tạo
r
h
ời này. Điề
m
chiếu, như
n
ì
biến này p
h
à
y sẽ bị bỏ
q
u
không kha
i
c
hiếu, chúng
36
d
anh của X
"<<&X<<en
d
d

anh Y= "<
<
17
7
: Kết quả c

việc khởi đ


r
a một biến t

u này gọi là
n
g điều này
h
ải được kh
a
q
ua. Chẳng
h
i
báo là stati
ta có thể g

d
l;

<
&Y<<endl;


a ví dụ 2.1
4

ng là một h

ạm thời ch

tham chiếu
r
ất nguy hi

a
i báo là
sta
t
h
ạn như đoạ
n
c thì điều n
à

i hàm ở ph
á

4

ằng, chẳng
h



a trị hằng v
à
độc lập (in
d

m. Khi hà
m
t
ic
, ngược l

n
chương trì
n
à
y rất nguy
h
á
i bên trái c


h
ạn như đoạ
n

à
biến tham
c
d

ependent re
m
trả về một
t

i tham chiế
u
n
h sau:
h
iểm.

a một phép
g

n

m
ã sau

c
hiếu
ference).
t
ham chiếu
u
tới nó thì
g
án.




1
2
3
4
5
6
7
8
9
1
1
1
1
1
1
1
1
1
1



Chúng
t
Chú
con trỏ
Chún
1

: #inclu
d
2
:

3
: int X
=
4
: //proto
5
: int &
M
6
:

7
: int mai
8
: {

9
: co
u
1
0: co
u
1
1: My
F

1
2: co
u
1
3: ret
1
4: }

1
5:

1
6: int &
1
7: {

1
8: ret
1
9: }

t
a chạy ví d

ý: Mặc dù
do đó chún
g
g ta không t
h
d

e <iostre
a
=
4;

type

M
yFunc();

n()

u
t<<"X="<<
X
u
t<<"X="<<
M
F
unc() = 2
0
u
t<<"X="<<
X
urn 0;

MyFunc()

urn X;




2.15, kết
q
biến tham
c
g
không thể
h
ể khai báo
C
a
m.h>
X
<<endl;

M
yFunc()<<
0
; //Ngh
ĩ
a
X
<<endl;

q
uả ở hình 2.
Hình 2.1
8
c

hiếu trông
g
được dùng
c
m
ột biến th
a
37
C
T2_15.CPP
endl;

l
à
X = 2
0
18
8
: Kết quả c

g
iống như là
c
ấp phát độ
n
a
m chiếu ch

0



a ví dụ 2.1
5
biến con tr

n
g.

đến biến t
h

5


nhưng chú
n

h
am chiếu h
o

n
g không th


o
ặc biến co
n



là biến

n
trỏ chỉ


2.
2
đến biế
n
đoạn
m
int *
2
.13 Phép đ
a
Với ng
ô
phươn
g
biên dị
c
2.2.13.
1
n
tham chiế
u
m
ã sau:
int

X
int
*
& Ref = P;
a
năng hóa
(
ô
n ngữ C++
,
g
pháp cung
c
h sẽ lựa ch

1
Đa năng
h
Trong ngôn
biệt. Đôi k
h
trả về trị tu
y
riêng cho
m
của một tha
m
int abs(int i
)
long la

b
s(l
o
double fabs
(
Tất cả các
h
khi phải có
b
hàm khác n
h
thể định ng
h
int abs(int i
)
long abs(lo
n
double abs(
d

1: #
2: #
3:

4: i
5: l
6:
d
7:


8: i
9: {
u
. Tuy nhiê
n
X
;
*
P = &X;
(
Overloadi
n
,
chúng ta c
ó
cấp nhiều h
ơ

n phiên bả
n
h
óa các hà
m
ngữ C cũn
g
h
i đây là mộ
t
y
ệt đối của

m
m
ỗi kiểu dữ l
i
m
số :
)
;
o
ng l);
(
double d);
h
àm này đều
b
a tên khác
h
au có cùng
h
ĩa lại các h
à
)
;
n
g l);
d
ouble d);
include <
i
include <

m
nt MyAbs(
i
ong MyAbs
(
d
ouble MyA
b
nt main()


n
chúng ta c
ó
n
g) :
ó
thể đa năn
g
ơ
n
m
ột định
n
thích hợp
c
m
(Function
s
g

như mọi n
g
t
điều phiều
t
m
ột tham số
i
ệu số, do v





cùng thực
h
nhau. C++
g
m
ột tên. Đ
â
à
m trả về trị



i
ostream.h
m
ath.h>


i
nt X);

(
long X);

b
s(double
38
ó
thể khai b
á
g
hóa các h
à
nghĩa cho t
ê
c
ủa hàm hay
s
overloadi
n
g
ôn ngữ má
y
t
oái. Chẳng
là số, vì cầ
n


y chúng ta
c




h
iện một ch

g
iải quyết đi
â
y chính là
đ
tuyệt đối đ




CT2_16
.
>
X);

á
o một biến
t
à
m và các to

á
ê
n hàm đã c
h
toán tử dựa
n
g) :

y
tính khác,
m
hạn như tro
n
n
thiết phải c
ó
c
ó tới ba hà
m





a năng nên
c
ều này bằn
g
đ
a năng hóa

h

thay thế cá
c


Ví dụ 2.
1
.
CPP
t
ham chiếu
v
á
n tử (opera
t
h
o trong cù
n
trên các th
a
m
ỗi hàm đề
u
n
g ngôn ng

ó

t

ên phân
b
m
khác nha
u




c
húng ta th

g
cách cho p
h
h
àm. Do đó
c
hàm trên
n


1
6:
v
ề biến con
t
t
or). Đa năn
g

n
g
m
ột phạ
m
a
m số mà nó
u
phải có m


C, có rất n
h
b
iệt nên C p
h
u
để trả về tr






y điều này
n
h
ép chúng t
a
trong C++

c
n
hư sau :


t
rỏ như
g
hóa là
m
vi. Trình
đ
ư
ợc gọi.

t tên phân
h
iều hàm
h
ải có hàm

tuyệt đối




n
ghịch lý
a
tạo ra các

c
húng ta có










10:
11:
12:
13:
14:
15:
la "
16:
17:
18:
19:
20:
21:

22:
23:
24:
25:

26:

27:
28:
29:
30:
31:

32:
33:
34:
35:



int X
=
long Y
double
cout<<
"
<<
M
cout<<
"

<<
M
cout<<
"

<<
M
return
}

int MyAbs
(
{

return
}

long MyAb
s
{

return
}

double My
A
{

return
}

=
-7;
= 200000l
Z = -

3
5.6
"
Tri tuyet
M
yAbs(X)<<
"
Tri tuyet
M
yAbs(Y)<<
"
Tri tuyet
M
yAbs(Z)<<
0;

(
int X)

abs(X);

s
(long X)

labs(X);

A
bs(double
fabs(X);


39
;

78;

doi cua
s
endl;

doi cua
s
endl;

doi cua
s
endl;

X)

s
o nguyen
(
s
o nguyen
(
s
o thuc "<
<
(
int) "<<

X
(
long int)
<
Z<<" la
"
X
<<" la "

"<<Y<<"
"



Trìn
h
chín
h
hạn
n
My
A
My
A
My
A
Quá
t
hợp
n

hàm
đ
tron
g
phiê
n
Chúng ta c
h
h
biên dịch
d
h
xác phiên
b
n
hư:
A
bs(-7); //Gọ
A
bs(-7
l
); //G

A
bs(-7.5); //
G
t
rình tìm đư

n

hập nhằng
c
đ
ược đa nă
n
g
lệnh gọi hà
n
bản nào ch
My
A
My
A
Các phép c
h
(chúng ta s

Chúng ta c
ũ
nào đó chú
n
phiên bản h
int (
lon
g
int (
pf1
=
pf2
=

pf3
=
Các giới

B

nha
u
h
ạy ví dụ 2.1
H
d
ựa vào sự k
h
b
ản cài đặt
n

i hàm int M
y

i hàm long
G
ọi hàm dou
b

c hàm đượ
c
c
ủa C++. C

h
n
g hóa mà c
ó
m thì phiên
o phép chu
y
A
bs(‘c’); //
G
A
bs(2.34f);
/
h
uyển kiểu
c

xem xét cá
c
ũ
ng có thể lấ
n
g ta có thể
l
àm nào có t
r
*pf1)(int);
g
(*pf2)(lon
g

*pf3)(doubl
e
=
MyAbs; /
/
=
MyAbs; /
/
=
MyAbs; /
/
hạn của việ
c

t kỳ hai hà
m
u
.
6 , kết quả

H
ình 2.19:
K
h
ác nhau về
n
ào của hàm

y
Abs(int)

MyAbs(lon
g
b
le MyAbs
(
c
đa năng h
ó
h
ẳng hạn nh
ư
ó
kiểu dữ liệ
u
bản hàm đó
y
ển kiểu dễ
d
G
ọi int MyA
b
/
/Gọi doubl
e
c
ó sẵn sẽ đư

c
phép chu
y

y địa chỉ củ
a
l
àm cho trìn
h
r
ong định n
g
g
);
e
);
/
Trỏ đến hà
m
/
Trỏ đến hà
m
/
Lỗi!!! (khô
n
c
đa năng h
ó
m
nào trong
t
40

hình 2.19

K
ết quả của
v
số các tha
m
MyAbs()
th
í


g
)
(
double)
ó
a cũng là q
u
ư
nếu tìm th

u
các tham
s
sẽ được gọ
i
d
àng nhất.
b
s(int)
e

MyAbs(do
u

c ưu tiên h
ơ
y
ển kiểu tự t

a
một hàm
đ
h
biên dịch
C
g
hĩa. Chẳng
m
int MyAb
s
m
long MyA
b
n
g có phiên
b
ó
a các hàm:
t
ập các hàm
v

í dụ 2.16
m
số, kiểu củ
a
í
ch hợp với
m




u
á trình đượ
c

y một phiê
n
s
ố của nó tr
ù
i
. Nếu khôn
g
u
ble)
ơ
n các phép

o ở chương
đ

ã được đa n
ă
C
++ biết đư

hạn như:
s
(int)
b
s(long)
b
ản hàm nà
o
đã đa năng
p
a
các tham
s
m
ột lệnh gọ
i




c
dùng để g
i
n
bản định

n
ù
ng với kiểu
g
trình biên
d
chuyển kiể
u
3).
ă
ng hóa sao

c chúng ta
o
để đối sán
h
p
hải có các
t
s
ố để có thể
x
i
hàm được
c




i

ải quyết cá
c
n
ghĩa nào đó
các tham s

d
ịch C++ sẽ
u
mà chúng
t
cho bằng
m
cần lấy địa
c
h
)
t
ham số khá

x
ác định
c
ho, chẳng




c
trường

của một

đã gởi tới
gọi đến
t
a tạo ra
m
ột cách
c
hỉ của
c




41

• Các hàm đa năng hóa với danh sách các tham số cùng kiểu chỉ dựa trên kiểu
trả về của hàm thì trình biên dịch báo lỗi. Chẳng hạn như, các khai báo sau là
không hợp lệ:
void Print(int X);
int Print(int X);
Không có cách nào để trình biên dịch nhận biết phiên bản nào được gọi nếu
giá trị trả về bị bỏ qua. Như vậy các phiên bản trong việc đa năng hóa phải có
sự khác nhau ít nhất về kiểu hoặc số tham số mà chúng nhậ
n được.
• Các khai báo bằng lệnh typedef không định nghĩa kiểu mới. Chúng chỉ thay
đổi tên gọi của kiểu đã có. Chúng không ảnh hưởng tới cơ chế đa năng hóa
hàm. Chúng ta hãy xem xét đoạn mã sau:
typedef char * PSTR;

void Print(char * Mess);
void Print(PSTR Mess);
Hai hàm này có cùng danh sách các tham số, do đó đoạn mã trên sẽ
phát sinh lỗi.
• Đối với kiểu mảng và con trỏ được xem như đồng nhất đối với sự phân biệt
khác nhau giữa các phiên bản hàm trong việc
đa năng hóa hàm. Chẳng hạn
như đoạn mã sau se phát sinh lỗi:
void Print(char * Mess);
void Print(char Mess[]);
Tuy nhiên, đối với mảng nhiều chiều thì có sự phân biệt giữa các phiên
bản hàm trong việc đa năng hóa hàm, chẳng hạn như đoạn mã sau hợp
lệ:
void Print(char Mess[]);
void Print(char Mess[][7]);
void Print(char Mess[][9][42]);
• const và các con trỏ (hay các tham chiếu) có thể dùng để phân biệt, chẳng
hạn như đoạn mã sau hợp lệ:
void Print(char *Mess);
void Print(const char *Mess);

2.2.13.
2
2
Đa năng
h
Trong ngôn
tác liên qua
n
mái.

Ví dụ 2.17:


1: #
2: /
3: t
4: {
5:
6:
7: }
8:

9:
10:
11:
12:
13:

14:
15:
16:
17:

18:
19:
20:
21:
h
óa các toá
n

ngữ C, khi
n
đến kiểu
d
Chương trì
n
include <
s
* Định ng
h
ypedef st
r

double
double
Complex;

Complex S
e
Complex A
d
Complex S
u
void Disp
l
int main(
v
{

Comple

x
C1 = S
e
C2 = S
e
printf
(
Displa
y
n
tử (Opera
t
chúng ta tự
t
d
ữ liệu đó th
ư
n
h cài đặt cá
c
s
tdio.h>
h
ĩa số ph

r
uct

Real;


Imaginar
y
e
tComplex(
d
dComplex(
u
bComplex(
l
ayComplex
v
oid)

x
C1,C2,C3
e
tComplex(
e
tComplex(
(
"\
n
So phu
y
Complex(C
42
t
ors overlo
a
t

ạo ra một k
ư
ờng thông
q
c
phép toán
CT2_17
.

c */

y
;

double R,
d
Complex C
1
Complex C
1
(Complex
C
,C4;

1.0,2.0);
-
3
.0,4.0)
;
c thu nha

t
1);

a
ding) :

iểu dữ liệu
m
q
ua các hà
m
cộng và trừ
.
CPP
d
ouble I);
1
,Complex
C
1
,Complex
C
C
);

;

t
:");


m
ới, chúng
t
m
, điều này t
r
số phức
C
2);

C
2);

t
a thực hiện
c
r
ở nên khôn
g
c
ác thao
g
thoải
43

22: printf("\nSo phuc thu hai:");
23: DisplayComplex(C2);

24: C3 = AddComplex(C1,C2); //Hơi bất tiện !!!
25: C4 = SubComplex(C1,C2);

26: printf("\nTong hai so phuc nay:");
27: DisplayComplex(C3);
28: printf("\nHieu hai so phuc nay:");
29: DisplayComplex(C4);
30: return 0;
31: }
32:
33: /* Đặt giá trị cho một số phức */
34: Complex SetComplex(double R,double I)
35: {
36: Complex Tmp;
37:
38: Tmp.Real = R;
39: Tmp.Imaginary = I;
40: return Tmp;
41: }
42: /* Cộng hai số phức */
43: Complex AddComplex(Complex C1,Complex C2)
44: {
45: Complex Tmp;
46:
47: Tmp.Real = C1.Real+C2.Real;
48: Tmp.Imaginary = C1.Imaginary+C2.Imaginary;

49:
50:
51:

52:
53:

54:
55:
56:

57:
58:
59:
60:
61:

62:
63:
64:
65:
66:



Chúng ta c
h
Trong chư
ơ
trừ hai số p
h
thực chất th
này, trong
C
return
}


/* Trừ ha
i
Complex S
u
{

Comple
x
Tmp.Re
a
Tmp.Im
a
return
}

/* Hiển t
h
void Disp
l
{

printf
(
}

h
ạy ví dụ 2.1
ơ
ng trình ở v
í

h
ức 1+2i và
ao tác cộng
C
++ cho phé
Tmp;
i
số phức
u
bComplex(
x
Tmp;

a
l = C1.Re
a
ginary =
Tmp;

h
ị số phức
l
ayComplex
(
"(%.1lf,%
7, kết quả

Hình
í
dụ 2.17, c

h
–3+4i; ngư

và trừ là cá
c
p chúng ta
c
44
*/

Complex C
1
al-
C
2.Rea
l
C1.Imagin
a
*/

(Complex
C
.1lf)",C.
R

hình 2.20
2.20: Kết q
u
h
úng ta nhậ

n

i lập t
r
ình
h
c
toán tử ch

c
ó thể định
n
1
,Complex
C
l
;

a
ry-
C
2.Ima
g
C
)

R
eal,C.Ima
g
u

ả của ví dụ
n
thấy với cá
c
h
oàn toàn k
h

không phả
i
n
ghĩa lại ch

C
2)

g
inary;

g
inary);

2.17
c
hàm vừa c
h
ông thoải
m
i
là hàm. Để


c năng của
c

ài đặt dùng
đ
m
ái khi sử dụ
n
khắc phục
y
c
ác toán tử
đ

đ
ể cộng và
n
g bởi vì
y
ếu điểm
đ
ã có sẵn

một cách ti

chương trìn
h
Ví dụ 2.18:


1: #
2: /
3: t
4: {
5:
6:
7: }
8:

9:
10:
11:
12:
13:

14:
15:
16:
17:

18:
19:
20:
21:
22:
23:
24:

n lợi và tự
n

h
ở ví dụ 2.
1
include <
i
/ Định ng
h
ypedef st
r

double
double
Complex;

Complex S
e
void Disp
l
Complex o
p
Complex o
p
int main(
v
{

Comple
x
C1 = S
e

C2 = S
e
cout<<
"
Displa
y
cout<<
"
Displa
y
C3 = C
1
n
hiên hơn r

1
7 được viết
i
ostream.h
h
ĩa số ph

r
uct

Real;

Imaginar
y
e

tComplex(
l
ayComplex
p
erator +
p
erator -
v
oid)

x
C1,C2,C3
e
tComplex(
e
tComplex(
"
\
n
So phuc
y
Complex(C
"
\
n
So phuc
y
Complex(C
1
+ C2;


45

t nhiều. Điề
u
t
như sau:
CT2_18
.
>

c

y
;

double R,
d
(Complex
C
(Complex
C
(
Complex
C
,C4;

1.0,2.0);
-
3

.0,4.0)
;
thu nhat
:
1);

thu hai:
"
2);

u
này gọi là
.
CPP
d
ouble I);
C
);

C
1,Complex
C
1,Complex
;

:
";

"
;


đa năng hó
a
C2);

C2);

a
toán tử. K
h
h
i đó
46

25: C4 = C1 - C2;
26: cout<<"\nTong hai so phuc nay:";

27: DisplayComplex(C3);
28: cout<<"\nHieu hai so phuc nay:";
29: DisplayComplex(C4);
30: return 0;
31: }
32:
33: //Đặt giá trị cho một số phức
34: Complex SetComplex(double R,double I)
35: {
36: Complex Tmp;
37:
38: Tmp.Real = R;
39: Tmp.Imaginary = I;

40: return Tmp;
41: }
42:
43: //Cộng hai số phức
44: Complex operator + (Complex C1,Complex C2)
45: {
46: Complex Tmp;
47:
48: Tmp.Real = C1.Real+C2.Real;
49: Tmp.Imaginary = C1.Imaginary+C2.Imaginary;
50: return Tmp;
51: }

52:

53:
54:
55:
56:
57:

58:
59:
60:
61:
62:

63:
64:
65:

66:
67:



Chúng ta c
h
Như vậy tr
o
tử toán học
sau:
C4
=
thì ở trong
C
//Trừ hai
Complex o
p
{

Comple
x
Tmp.Re
a
Tmp.Im
a
return
}

//Hiển th


void Disp
l
{

cout<<
"
}

h
ạy ví dụ 2.1
H
o
ng C++, cá
c
chuẩn chứ
k
=
AddComp
l
C
++, chúng
t
số phức

p
erator -
x
Tmp;


a
l = C1.Re
a
ginary =
Tmp;


số phức

l
ayComplex
"
("<<C.Rea
8, kết quả

H
ình 2.21:
K
c
phép toán
t
k
hông phải
b
l
ex(C3, Sub
C
t
a có lệnh t
ư

47
(
Complex
C
al-
C
2.Rea
l
C1.Imagin
a
(Complex
C
l
<<","<<C
.

hình 2.21
K
ết quả của
v
tr
ên các giá
t
b
ằng các tên
C
omplex(C
1
ư
ơng ứng nh

ư
C
1,Complex
l
;

a
ry-
C
2.Ima
g
C
)

.
Imaginary
<
v
í dụ 2.18
t
rị kiểu số p
h
hàm như tr
o
1
,C2));
ư
sau:
C2)


g
inary;

<
<")";

h
ức được th

o
ng C. Chẳn
g


c hiện bằn
g
g
hạn chún
g

g
các toán
g
ta có lệnh
48

C4 = C3 + C1 - C2;
Chúng ta nhận thấy rằng cả hai lệnh đều cho cùng kết quả nhưng lệnh của C++ thì dễ hiểu
hơn. C++ làm được điều này bằng cách tạo ra các hàm định nghĩa cách thực hiện của một
toán tử cho các kiểu dữ liệu tự định nghĩa. Một hàm định nghĩa một toán tử có cú pháp sau:

data_type operator operator_symbol ( 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ó).
Trong chương trình ví dụ 2.18, toán tử + là toán tử gồm hai toán hạng (gọi là toán tử hai ngôi;
toán tử một ngôi là toán tử chỉ có một toán hạng) và trình biên dịch biết tham số đầu tiên là ở
bên trái toán tử, còn tham số thứ hai thì ở bên phải của toán tử. Trong trường hợp lập trình
viên quen thuộc với cách gọi hàm, C++ vẫn cho phép bằng cách viết như sau:
C3 = operator + (C1,C2);
C4 = operator - (C1,C2);
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 cũng theo cách thức tương
tự như việc chọn lựa giữa các hàm được đa năng hóa là 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. Chúng ta sẽ tìm hiểu kỹ về việc đa năng
hóa các toán tử trong chương 4.
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ử Ý nghĩa
::
Toán tử định phạm vi.
.*

Truy cập đến con trỏ là trường của struct hay thành
49

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 & |
~ *= /= %= >>= ==
!= , -> ->*

Các toán tử được phân loại như sau :

 Các toán tử một ngôi : * & ~ ! ++ sizeof
(data_type)
Các toán tử này được định nghĩa chỉ có một
tham số và phải trả về một giá trị cùng kiểu với
tham số của chúng. Đối với toán tử sizeof phải
trả về một giá trị kiểu size_t (định nghĩa trong
stddef.h)
Toán tử (data_type) được dùng để chuyển đổi
kiểu, nó phải tr
ả về một giá trị có kiểu là
data_type.
50

 Các toán tử hai ngôi:
* / % + - >> << > <
>= <= == != & | ^ && ||
Các toán tử này được định nghĩa có hai tham số.
 Các phép gán: = += -= *= /= %= >>= <<=
^= |=
Các toán tử gán được định nghĩa chỉ có một
tham số. Không có giới hạn về kiểu của tham số
và kiểu trả về của phép gán.
 Toán tử lấy thành viên : ->
 Toán tử lấy phần tử theo chỉ số: []
 Toán tử gọi hàm: ()
3.1 DẪN NHẬP
Bây giờ chúng ta bắt đầu tìm hiểu về lập trình hướng đối tượng trong C++. Trong các phần sau, chúng ta
cũng tìm hiểu về các kỹ thuật của thiết kế hướng đối tượng (Object-Oriented Design OOD): Chúng ta phân
tích một vấn đề cụ thể, xác định các đối tượng nào cần để cài đặt hệ thống, xác định các thuộc tính nào mà
đối tượng phải có, xác định hành vi nào mà đối tượng cần đưa ra, và chỉ rõ làm thế nào các đối tượng cần

tương tác với đối tượng khác để thực hiện các mục tiêu tổng thể của hệ thống.
Chúng ta nhắc lại các khái niệm và thuật ngữ chính của đính hướng đối tượng. OOP đóng gói dữ liệu (các
thuộc tính) và các hàm (hành vi) thành gói gọi là các đối tượng. Dữ liệu và các hàm của đối tượng có sự liên
hệ mật thiết với nhau. Các đối tượng có các đặc tính của việc che dấu thông tin. Đi
ều này nghĩa là mặc dù
các đối tượng có thể biết làm thế nào liên lạc với đối tượng khác thông qua các giao diện hoàn toàn xác định,
bình thường các đối tượng không được phép biết làm thế nào các đối tượng khác được thực thi, các chi tiết
của sự thi hành được dấu bên trong các đối tượng.
Trong C và các ngôn ngữ lập trình thủ tục, lập trình có khuynh hướng định hướng hành động, trong khi ý
tưởng trong lập trình C++ là định hướng đối tượng. Trong C, đơn vị c
ủa lập trình là hàm; trong C++, đơn vị
của lập trình là lớp (class) .
Các lập trình viên C tập trung vào viết các hàm. Các nhóm của các hành động mà thực hiện vài công việc
được tạo thành các hàm, và các hàm được nhóm thành các chương trình. Dữ liệu thì rất quan trọng trong C,
nhưng quan điểm là dữ liệu tồn tại chính trong việc hỗ trợ các hàm động mà hàm thực hiện. Các động từ
trong một hệ thống giúp cho lập trình viên C xác định tập các hàm mà sẽ hoạt động cùng vớ
i việc thực thi hệ
thống.
Các lập trình viên C++ tập trung vào việc tạo ra "các kiểu do người dùng định nghĩa" (user-defined types)
gọi là các lớp. Các lớp cũng được tham chiếu như "các kiểu do lập trình viên định nghĩa" (programmer-
defined types). Mỗi lớp chứa dữ liệu cũng như tập các hàm mà xử lý dữ liệu. Các thành phần dữ liệu của
một lớp được gọi là "các thành viên dữ liệu" (data members). Các thành phần hàm của một lớ
p được gọi là

×