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
<< 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
ị
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
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
ú
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
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
à
.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
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
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;
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: }
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
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
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
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
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
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
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
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
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
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
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.
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 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
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
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
ụ
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
ủ
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
ể
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
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
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
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
á
ê
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
ê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
n1
6:
v
ề biến con
t
t
or). Đa năn
g
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
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
int X
=
long Y
double
cout<<
"
<<
M
cout<<
"
<<
M
cout<<
"
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);
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ậ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
=
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
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
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
í 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
đ
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
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;
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
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;
ạ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
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);
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
}
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
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 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:
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
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;
.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
;
:
";
"
;
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:
ị
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;
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
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:
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 :
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à