202 PF Chapter 6 Basic OOP P 2

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 49

OOP (P.

2)

ThS.
Trần Ngọc Bảo Duy

Lập trình hướng đối tượng (P.2)


Đặc tính đặc biệt của
thành viên
Tính static
Tính const

Kỹ thuật Lập trình (CO1027) Quan hệ bạn bè


Ngày 11 tháng 8 năm 2022 Hàm bạn bè
Lớp bạn bè

Tổ chức mã nguồn
cho các lớp

ThS. Trần Ngọc Bảo Duy


Khoa Khoa học và Kỹ thuật Máy tính
Trường Đại học Bách Khoa, ĐHQG-HCM

OOP (P.2).1
OOP (P.2)
Tổng quan
ThS.
Trần Ngọc Bảo Duy

1 Đặc tính đặc biệt của thành viên


Tính static Đặc tính đặc biệt của
thành viên
Tính const Tính static
Tính const

Quan hệ bạn bè
Hàm bạn bè

2 Quan hệ bạn bè Lớp bạn bè

Tổ chức mã nguồn
Hàm bạn bè cho các lớp
Lớp bạn bè

3 Tổ chức mã nguồn cho các lớp

OOP (P.2).2
OOP (P.2)

ThS.
Trần Ngọc Bảo Duy

Đặc tính đặc biệt của


thành viên

ĐẶC TÍNH ĐẶC BIỆT Tính static


Tính const

Quan hệ bạn bè
Hàm bạn bè

CỦA THÀNH VIÊN Lớp bạn bè

Tổ chức mã nguồn
cho các lớp

OOP (P.2).3
OOP (P.2)
Thành viên có tính static
ThS.
Trần Ngọc Bảo Duy

• Thuộc tính và phương thức đều có thể có tính static


nếu ta đặt từ khóa static trước các khai báo của các Đặc tính đặc biệt của
thành viên
thành viên. Tính static
Tính const

class X { Quan hệ bạn bè


public : Hàm bạn bè
Lớp bạn bè
static int a ;
static void foo () { } Tổ chức mã nguồn
cho các lớp
};

OOP (P.2).4
OOP (P.2)
Thành viên có tính static
ThS.
Trần Ngọc Bảo Duy

• Thuộc tính và phương thức đều có thể có tính static


nếu ta đặt từ khóa static trước các khai báo của các Đặc tính đặc biệt của
thành viên
thành viên. Tính static
Tính const

class X { Quan hệ bạn bè


public : Hàm bạn bè
Lớp bạn bè
static int a ;
static void foo () { } Tổ chức mã nguồn
cho các lớp
};

• Ý nghĩa chung: thành viên được sử dụng chung cho


toàn bộ tất cả các đối tượng của lớp.

OOP (P.2).4
OOP (P.2)
Thuộc tính có tính static
ThS.
Trần Ngọc Bảo Duy

• Vùng nhớ cho nó không được tạo riêng cho mỗi đối
Đặc tính đặc biệt của
tượng như trường hợp của thuộc tính non-static. thành viên

• Vùng nhớ cho nó được cấp 1 lần, chỉ một vùng, và Tính static
Tính const

dùng chung cho tất cả các đối tượng được tạo ra từ Quan hệ bạn bè
Hàm bạn bè
lớp đó. Lớp bạn bè

• Vùng nhớ này được khởi tạo giá trị (bằng 0) trước khi Tổ chức mã nguồn
cho các lớp
đối tượng đầu tiên của lớp được tạo ra.
• Thời gian sống của vùng nhớ này là thời gian sống của
toàn bộ chương trình.

OOP (P.2).5
OOP (P.2)
Thuộc tính non-static: Ví dụ
ThS.
class Date { Trần Ngọc Bảo Duy
private :
int day , month , year ;
public :
Date ( int day , int month ,
int year )
Đặc tính đặc biệt của
{ thành viên
this - > day = day ; Tính static
this - > month = month ; Tính const

this - > year = year ; Quan hệ bạn bè


} Hàm bạn bè
Lớp bạn bè

void print () {} Tổ chức mã nguồn


}; cho các lớp
int main () {
Date d1 (29 , 3 , 2021);
Date d2 (3 , 12 , 2021);
Date d3 (15 , 12 , 2021);

d1 . print ();
d2 . print ();
d3 . print ();

return 0;
}
OOP (P.2).6
OOP (P.2)
Thuộc tính non-static: Ví dụ
ThS.
class Date { Trần Ngọc Bảo Duy
private : day 29
int day , month , year ; month 3
public :
Date ( int day , int month , d1 year 2021

int year )
` print Đặc tính đặc biệt của
{ thành viên
this - > day = day ; Tính static
this - > month = month ; Tính const

this - > year = year ; day 3 Quan hệ bạn bè


} Hàm bạn bè
month 12 Lớp bạn bè

void print () {} d2 year 2021 Tổ chức mã nguồn


}; cho các lớp
int main () { ` print
Date d1 (29 , 3 , 2021);
Date d2 (3 , 12 , 2021);
Date d3 (15 , 12 , 2021);
day 15

d1 . print (); month 12


d2 . print ();
d3 . print ();
d3 year 2021

return 0; ` print
}
OOP (P.2).6
OOP (P.2)
Thuộc tính static: Ví dụ
ThS.
class Date { Trần Ngọc Bảo Duy
private :
int day , month , year ;
public : id 0
static int id ;
Date ( int day , int month ,
Đặc tính đặc biệt của
int year ) thành viên
{
day 29 Tính static
this - > day = day ; Tính const

this - > month = month ; month 3


Quan hệ bạn bè
this - > year = year ; d1 year 2021 Hàm bạn bè

} Lớp bạn bè

Tổ chức mã nguồn
` print cho các lớp
void print () {}
int getId () { return id ++; }
};
int main () { day 3
Date d1 (29 , 3 , 2021); month 12
Date d2 (3 , 12 , 2021);
d2 year 2021

cout << d1 . getId ();


cout << d2 . getId (); ` print

return 0;
}
OOP (P.2).7
OOP (P.2)
Thuộc tính static: Ví dụ
ThS.
class Date { Trần Ngọc Bảo Duy
private :
int day , month , year ;
public : id 1
static int id ;
Date ( int day , int month ,
Đặc tính đặc biệt của
int year ) thành viên
{
day 29 Tính static
this - > day = day ; Tính const

this - > month = month ; month 3


Quan hệ bạn bè
this - > year = year ; d1 year 2021 Hàm bạn bè

} Lớp bạn bè

Tổ chức mã nguồn
` print cho các lớp
void print () {}
int getId () { return id ++; }
};
int main () { day 3
Date d1 (29 , 3 , 2021); month 12
Date d2 (3 , 12 , 2021);
d2 year 2021

cout << d1 . getId ();


cout << d2 . getId (); ` print

return 0;
}
OOP (P.2).7
OOP (P.2)
Thuộc tính static: Ví dụ
ThS.
class Date { Trần Ngọc Bảo Duy
private :
int day , month , year ;
public : id 2
static int id ;
Date ( int day , int month ,
Đặc tính đặc biệt của
int year ) thành viên
{
day 29 Tính static
this - > day = day ; Tính const

this - > month = month ; month 3


Quan hệ bạn bè
this - > year = year ; d1 year 2021 Hàm bạn bè

} Lớp bạn bè

Tổ chức mã nguồn
` print cho các lớp
void print () {}
int getId () { return id ++; }
};
int main () { day 3
Date d1 (29 , 3 , 2021); month 12
Date d2 (3 , 12 , 2021);
d2 year 2021

cout << d1 . getId ();


cout << d2 . getId (); ` print

return 0;
}
OOP (P.2).7
OOP (P.2)
Phương thức có tính static
ThS.
Trần Ngọc Bảo Duy

Định nghĩa
Phương thức có tính static là phương thức không của riêng
Đặc tính đặc biệt của
bất kỳ đối tượng nào. Vì vậy: thành viên
Tính static
1 Không thể gọi đến phương thức loại này bằng một đối Tính const

tượng cụ thể. Quan hệ bạn bè


Hàm bạn bè
Lớp bạn bè

Tổ chức mã nguồn
cho các lớp

OOP (P.2).8
OOP (P.2)
Phương thức có tính static
ThS.
Trần Ngọc Bảo Duy

Định nghĩa
Phương thức có tính static là phương thức không của riêng
Đặc tính đặc biệt của
bất kỳ đối tượng nào. Vì vậy: thành viên
Tính static
1 Không thể gọi đến phương thức loại này bằng một đối Tính const

tượng cụ thể. Quan hệ bạn bè


Hàm bạn bè

2 Trong phương thức dạng này, con trỏ this không có Lớp bạn bè

giá trị, do đó việc dùng con trỏ this sẽ có lỗi. Tổ chức mã nguồn
cho các lớp

OOP (P.2).8
OOP (P.2)
Phương thức có tính static
ThS.
Trần Ngọc Bảo Duy

Định nghĩa
Phương thức có tính static là phương thức không của riêng
Đặc tính đặc biệt của
bất kỳ đối tượng nào. Vì vậy: thành viên
Tính static
1 Không thể gọi đến phương thức loại này bằng một đối Tính const

tượng cụ thể. Quan hệ bạn bè


Hàm bạn bè

2 Trong phương thức dạng này, con trỏ this không có Lớp bạn bè

giá trị, do đó việc dùng con trỏ this sẽ có lỗi. Tổ chức mã nguồn
cho các lớp

3 Phương thức static không thể gọi trực tiếp các phương
thức non-static khác.

OOP (P.2).8
OOP (P.2)
Phương thức có tính static
ThS.
Trần Ngọc Bảo Duy

Định nghĩa
Phương thức có tính static là phương thức không của riêng
Đặc tính đặc biệt của
bất kỳ đối tượng nào. Vì vậy: thành viên
Tính static
1 Không thể gọi đến phương thức loại này bằng một đối Tính const

tượng cụ thể. Quan hệ bạn bè


Hàm bạn bè

2 Trong phương thức dạng này, con trỏ this không có Lớp bạn bè

giá trị, do đó việc dùng con trỏ this sẽ có lỗi. Tổ chức mã nguồn
cho các lớp

3 Phương thức static không thể gọi trực tiếp các phương
thức non-static khác.
4 Phương thức static có thể:
• Truy xuất thuộc tính có tính static.
• Gọi các phương thức có tính static khác.

OOP (P.2).8
OOP (P.2)
Thành viên có tính static: Minh họa
ThS.
Trần Ngọc Bảo Duy

Với lớp Complex đã hiện thực:


Đặc tính đặc biệt của
• Người ta cần lưu trữ thêm thông tin về định dạng xuất thành viên
Tính static
ra màn hình khi in: Tính const

1 Dạng đại số. Quan hệ bạn bè

2 Dạng lượng giác (số đo góc theo số đo độ).


Hàm bạn bè
Lớp bạn bè

3 Dạng lượng giác (số đo góc theo radian). Tổ chức mã nguồn


cho các lớp
• Giả định, định dạng này là thiết lập cho toàn bộ các
đối tượng của lớp Complex kể từ thời điểm thiết lập
định dạng.

OOP (P.2).9
OOP (P.2)
Thành viên có tính static: Minh họa
ThS.
Trần Ngọc Bảo Duy

1 enum cformat { ALGEBRAIC , DEGREE , RADIAN };


2 class Complex {
3 public : Đặc tính đặc biệt của
thành viên
4 static cformat format ;
Tính static
5 Tính const

6 // Other defined members Quan hệ bạn bè


7 }; Hàm bạn bè
Lớp bạn bè
8
Tổ chức mã nguồn
9 cformat Complex :: format = ALGEBRAIC ; cho các lớp

OOP (P.2).10
OOP (P.2)
Thành viên có tính static: Minh họa
ThS.
Trần Ngọc Bảo Duy

1 enum cformat { ALGEBRAIC , DEGREE , RADIAN };


2 class Complex {
3 public : Đặc tính đặc biệt của
thành viên
4 static cformat format ;
Tính static
5 Tính const

6 // Other defined members Quan hệ bạn bè


7 }; Hàm bạn bè
Lớp bạn bè
8
Tổ chức mã nguồn
9 cformat Complex :: format = ALGEBRAIC ; cho các lớp

• Dòng 4: Khai báo bên trong lớp, dùng từ khoá static.


• Dòng 9: Khởi động bên ngoài phạm vi lớp, dùng tên
đầy đủ, sử dụng tiếp đầu ngữ: Complex::, không dùng
từ khoá static.

OOP (P.2).10
OOP (P.2)
Thành viên có tính static: Minh họa
ThS.
Trần Ngọc Bảo Duy
1 enum cformat { ALGEBRAIC , DEGREE , RADIAN };
2 class Complex {
3 public :
4 static cformat format ;
5 // Other defined members
Đặc tính đặc biệt của
6 }; thành viên
7 Tính static
Tính const
8 cformat Complex :: format = ALGEBRAIC ;
Quan hệ bạn bè
9
Hàm bạn bè
10 int main () { Lớp bạn bè

11 Complex c1 ; Tổ chức mã nguồn


cho các lớp
12 c1 . format = DEGREE ;
13
14 Complex c2 ;
15 cout << ( c2 . format == DEGREE );
16
17 return 0;
18 }

OOP (P.2).11
OOP (P.2)
Thành viên có tính static: Minh họa
ThS.
Trần Ngọc Bảo Duy
1 enum cformat { ALGEBRAIC , DEGREE , RADIAN };
2 class Complex {
3 public :
4 static cformat format ;
5 // Other defined members
Đặc tính đặc biệt của
6 }; thành viên
7 Tính static
Tính const
8 cformat Complex :: format = ALGEBRAIC ;
Quan hệ bạn bè
9
Hàm bạn bè
10 int main () { Lớp bạn bè

11 Complex c1 ; Tổ chức mã nguồn


cho các lớp
12 c1 . format = DEGREE ;
13
14 Complex c2 ;
15 cout << ( c2 . format == DEGREE );
16
17 return 0;
18 }

Cả hai đối tượng c1 và c2 dùng chung vùng nhớ format. Do


vậy, khi c1 thay đổi thì c2 cũng nhìn thấy sự thay đổi đó.
OOP (P.2).11
OOP (P.2)
Thành viên có tính static: Minh họa
ThS.
1 enum cformat { ALGEBRAIC , DEGREE , RADIAN }; Trần Ngọc Bảo Duy
2 class Complex {
3 public :
4 static cformat format ;
5 // Other defined members
6 }; Đặc tính đặc biệt của
thành viên
7
Tính static
8 cformat Complex :: format = ALGEBRAIC ; Tính const

9 Quan hệ bạn bè
10 int main () { Hàm bạn bè
Lớp bạn bè
11 Complex c1 ;
Tổ chức mã nguồn
12 Complex :: format = DEGREE ; cho các lớp
13
14 Complex c2 ;
15 cout << ( Complex :: format == DEGREE );
16
17 return 0;
18 }

OOP (P.2).12
OOP (P.2)
Thành viên có tính static: Minh họa
ThS.
1 enum cformat { ALGEBRAIC , DEGREE , RADIAN }; Trần Ngọc Bảo Duy
2 class Complex {
3 public :
4 static cformat format ;
5 // Other defined members
6 }; Đặc tính đặc biệt của
thành viên
7
Tính static
8 cformat Complex :: format = ALGEBRAIC ; Tính const

9 Quan hệ bạn bè
10 int main () { Hàm bạn bè
Lớp bạn bè
11 Complex c1 ;
Tổ chức mã nguồn
12 Complex :: format = DEGREE ; cho các lớp
13
14 Complex c2 ;
15 cout << ( Complex :: format == DEGREE );
16
17 return 0;
18 }
Một số trình biên dịch sẽ warning khi truy xuất thành viên có tính
static bằng cách sử dụng như một thành viên của một đối tượng. Vì
vậy, hãy sử dụng tiếp đầu ngữ Complex:: (<Tên lớp>::). OOP (P.2).12
OOP (P.2)
Thành viên có tính static: Minh họa
ThS.
Trần Ngọc Bảo Duy

Giả sử, ta cần cung cấp phương thức để lấy số phức liên
hợp. Có thể đặt ra các thiết kế như sau:
1 Gọi được phương thức conj() trên đối tượng c, tức là Đặc tính đặc biệt của
thành viên
c.conj(). Phương thức conj() đó thực hiện tính liên Tính static
Tính const
hợp trên c và trả về chính c. Quan hệ bạn bè
Hàm bạn bè
1 class Complex { Lớp bạn bè
2 public : Tổ chức mã nguồn
3 Complex conj () { cho các lớp
4 this - > img = - this - > img ;
5 return * this ;
6 }
7 };

Cách này không dùng static, nhưng làm thay đổi c.

OOP (P.2).13
OOP (P.2)
Thành viên có tính static: Minh họa
ThS.
Trần Ngọc Bảo Duy
Giả sử, ta cần cung cấp phương thức để lấy số phức liên
hợp. Có thể đặt ra các thiết kế như sau:
2 Gọi được phương thức conj() trên đối tượng c, tức là
c.conj(). Phương thức conj() đó tạo ra một số phức Đặc tính đặc biệt của
thành viên
trung gian, liên hợp số phức này và trả về số phức trung Tính static
Tính const
gian đó.
Quan hệ bạn bè
1 class Complex { Hàm bạn bè
Lớp bạn bè
2 public :
Tổ chức mã nguồn
3 Complex conj () { cho các lớp
4 Complex c2 ( this - > real ,
5 - this - > img );
6 return c2 ;
7 }
8 };

Cách này không dùng static và đồng thời cũng không


thay đổi c.

OOP (P.2).13
OOP (P.2)
Thành viên có tính static: Minh họa
ThS.
Trần Ngọc Bảo Duy

Giả sử, ta cần cung cấp phương thức để lấy số phức liên
hợp. Có thể đặt ra các thiết kế như sau: Đặc tính đặc biệt của
thành viên
3 Nếu bản thiết kế yêu cầu phải cung cấp cả hai tình Tính static
Tính const

huống: c thay đổi và c không bị thay đổi. Lúc này phải Quan hệ bạn bè
dùng đến static. Hàm bạn bè
Lớp bạn bè

• Phương thức non-static như (1): Complex conj() là Tổ chức mã nguồn


cho các lớp
nhằm liên hợp và trả về chính số phức hiện tại.
• Phương thức static: Complex conj(const Complex&):
Phương thức này tạo ra số phức trung gian, thực hiện
liên hợp và trả về số phức trung gian đó.

OOP (P.2).13
OOP (P.2)
Thành viên có tính static: Minh họa
ThS.
1 class Complex { Trần Ngọc Bảo Duy
2 public :
3 Complex conj () {
4 this - > img = - this - > img ;
5 return * this ;
6 }
Đặc tính đặc biệt của
7 thành viên
8 static Complex conj ( const Complex & rhs ) { Tính static
Tính const
9 Complex c2 ( rhs . real ,
10 - rhs . img ); Quan hệ bạn bè
11 return c2 ; Hàm bạn bè
Lớp bạn bè
12 }
13 }; Tổ chức mã nguồn
cho các lớp
14 int main () {
15 Complex c1 (1 , 3);
16 c1 . conj ();
17 c1 . print ();
18
19 Complex c2 (1 , 4);
20 Complex c3 = Complex :: conj ( c2 );
21 c3 . print ();
22
23 return 0;
24 }
OOP (P.2).14
OOP (P.2)
Thuộc tính có tính const
ThS.
Trần Ngọc Bảo Duy

Định nghĩa
Đặc tính đặc biệt của
Thuộc tính có tính const sẽ không cho phép sự thay đổi giá thành viên
Tính static
trị kể từ sau khi khởi động giá trị của nó, đòi hỏi khi khởi Tính const

động giá trị của thuộc tính const bằng cách khởi động trên Quan hệ bạn bè
Hàm bạn bè
cùng hàm khởi tạo. Lớp bạn bè

Tổ chức mã nguồn
cho các lớp

OOP (P.2).15
OOP (P.2)
Thuộc tính có tính const
ThS.
Trần Ngọc Bảo Duy

Định nghĩa
Đặc tính đặc biệt của
Thuộc tính có tính const sẽ không cho phép sự thay đổi giá thành viên
Tính static
trị kể từ sau khi khởi động giá trị của nó, đòi hỏi khi khởi Tính const

động giá trị của thuộc tính const bằng cách khởi động trên Quan hệ bạn bè
Hàm bạn bè
cùng hàm khởi tạo. Lớp bạn bè

Tổ chức mã nguồn
cho các lớp

Ứng dụng: Giúp cho người lập trình duy trì một giá trị là
hằng số suốt trong thời gian sống của đối tượng và gắn với
mỗi đối tượng.

OOP (P.2).15
OOP (P.2)
Phương tính có tính const
ThS.
Trần Ngọc Bảo Duy

Định nghĩa
Phương tính có tính const sẽ không thể thay đổi bất kỳ Đặc tính đặc biệt của
thuộc tính thành viên nào của lớp, nghĩa là, phương thức thành viên
Tính static

chỉ đọc giá trị của các thuộc tính thành viên. Với một ngoại Tính const

lệ, phương thức dạng này có thể thay đổi thuộc tính thành Quan hệ bạn bè
Hàm bạn bè

viên nếu biến đó khai báo tường minh với từ khoá mutable. Lớp bạn bè

Tổ chức mã nguồn
cho các lớp

OOP (P.2).16
OOP (P.2)
Phương tính có tính const
ThS.
Trần Ngọc Bảo Duy

Định nghĩa
Phương tính có tính const sẽ không thể thay đổi bất kỳ Đặc tính đặc biệt của
thuộc tính thành viên nào của lớp, nghĩa là, phương thức thành viên
Tính static

chỉ đọc giá trị của các thuộc tính thành viên. Với một ngoại Tính const

lệ, phương thức dạng này có thể thay đổi thuộc tính thành Quan hệ bạn bè
Hàm bạn bè

viên nếu biến đó khai báo tường minh với từ khoá mutable. Lớp bạn bè

Tổ chức mã nguồn
cho các lớp

Ứng dụng: Trong một dự án có nhiều người tham gia, hạn


chế truy xuất bằng cách dùng const như thế này sẽ tăng
tính toàn vẹn dữ liệu, đảm bảo dữ liệu luôn luôn trong trạng
thái đúng.

OOP (P.2).16
OOP (P.2)
Thành viên có tính hằng: Minh họa
ThS.
1 class X { Trần Ngọc Bảo Duy
2 private :
3 int noncon st_val ue ;
4 const int const_value ;
5 int mutable mutable_value ;
6 public :
7 X ( int value ): Đặc tính đặc biệt của
thành viên
8 const_value ( value ) ,
Tính static
9 non const_ value (100) , Tính const
10 mutable_value (200) {}
Quan hệ bạn bè
11
Hàm bạn bè
12 int process () const { Lớp bạn bè

13 int rs ; Tổ chức mã nguồn


14 rs = const_value + n oncons t_valu e ; cho các lớp
15 // const_value = 100;
16 // no nconst _value = 100;
17 mutable_value = 100;
18 rs += mutable_value ;
19 return rs ;
20 }
21 };
• Dòng 3: Khai báo một thuộc tính không có tính const, cũng không
có tính mutable.
• Dòng 4: Khai báo một thuộc tính có tính const.
• Dòng 5: Khai báo một thuộc tính có tính mutable. OOP (P.2).17
OOP (P.2)
Thành viên có tính hằng: Minh họa
ThS.
1 class X { Trần Ngọc Bảo Duy

2 private :
3 int noncon st_val ue ;
4 const int const_value ;
5 int mutable mutable_value ;
6 public : Đặc tính đặc biệt của
7 X ( int value ): thành viên
8 const_value ( value ) , Tính static
Tính const
9 non const_ value (100) ,
10 mutable_value (200) {} Quan hệ bạn bè
Hàm bạn bè
11
Lớp bạn bè
12 int process () const {
13 int rs ; Tổ chức mã nguồn
cho các lớp
14 rs = const_value + n oncons t_valu e ;
15 // const_value = 100;
16 // no nconst _value = 100;
17 mutable_value = 100;
18 rs += mutable_value ;
19 return rs ;
20 }
21 };

• Dòng 12: Khai báo một phương thức có tính const, từ khóa này đặt
sau danh sách tham số và trước thân của định nghĩa hàm.
OOP (P.2).17
OOP (P.2)
Thành viên có tính hằng: Minh họa
ThS.
1 class X { Trần Ngọc Bảo Duy
2 private :
3 int noncon st_val ue ;
4 const int const_value ;
5 int mutable mutable_value ;
6 public : Đặc tính đặc biệt của
7 X ( int value ): thành viên
8 const_value ( value ) , Tính static
Tính const
9 non const_ value (100) ,
10 mutable_value (200) {} Quan hệ bạn bè
Hàm bạn bè
11
Lớp bạn bè
12 int process () const {
13 int rs ; Tổ chức mã nguồn
cho các lớp
14 rs = const_value + n oncons t_valu e ;
15 // const_value = 100;
16 // no nconst _value = 100;
17 mutable_value = 100;
18 rs += mutable_value ;
19 return rs ;
20 }
21 };

• Dòng 17: Dù phương thức có tính const nhưng vẫn có thể thay đổi
giá trị của thuộc tính có tính mutable.
OOP (P.2).17
OOP (P.2)
Thành viên có tính hằng: Minh họa
ThS.
1 class X { Trần Ngọc Bảo Duy
2 private :
3 int noncon st_val ue ;
4 const int const_value ;
5 int mutable mutable_value ;
6 public :
7 X ( int value ): Đặc tính đặc biệt của
thành viên
8 const_value ( value ) , Tính static
9 non const_ value (100) , Tính const

10 mutable_value (200) {} Quan hệ bạn bè


11 Hàm bạn bè

12 int process () const { Lớp bạn bè

13 int rs ; Tổ chức mã nguồn


14 rs = const_value + n oncons t_valu e ; cho các lớp
15 // const_value = 100;
16 // no nconst _value = 100;
17 mutable_value = 100;
18 rs += mutable_value ;
19 return rs ;
20 }
21 };

• Dòng 15: Nếu có dòng này thì chương trình sẽ bị lỗi, vì thuộc tính
có tính const thì dù phương thức có tính const hay không thì cũng
không thể thay đổi được giá trị khi đã khởi động trong hàm khởi tạo.
OOP (P.2).17
OOP (P.2)
Thành viên có tính hằng: Minh họa
ThS.
1 class X { Trần Ngọc Bảo Duy
2 private :
3 int noncon st_val ue ;
4 const int const_value ;
5 int mutable mutable_value ;
6 public :
7 X ( int value ): Đặc tính đặc biệt của
thành viên
8 const_value ( value ) , Tính static
9 non const_ value (100) , Tính const

10 mutable_value (200) {} Quan hệ bạn bè


11 Hàm bạn bè

12 int process () const { Lớp bạn bè

13 int rs ; Tổ chức mã nguồn


14 rs = const_value + n oncons t_valu e ; cho các lớp
15 // const_value = 100;
16 // no nconst _value = 100;
17 mutable_value = 100;
18 rs += mutable_value ;
19 return rs ;
20 }
21 };

• Dòng 16: Nếu có dòng này thì chương trình sẽ bị lỗi, vì thuộc tính
không const, không mutable sẽ không thể bị thay đổi giá trị trong
phương thức có tính const.
OOP (P.2).17
OOP (P.2)

ThS.
Trần Ngọc Bảo Duy

Đặc tính đặc biệt của


thành viên
Tính static

QUAN HỆ BẠN BÈ
Tính const

Quan hệ bạn bè
Hàm bạn bè
Lớp bạn bè

Tổ chức mã nguồn
cho các lớp

OOP (P.2).18
OOP (P.2)
Quan hệ bạn bè (friendship)
ThS.
Trần Ngọc Bảo Duy

• Giả sử lớp ClassA và ClassB là hai lớp độc lập, không


có quan hệ thừa kế. Các phương thức thành viên của
ClassA không thể truy cập các thành viên (thuộc tính Đặc tính đặc biệt của
& phương thức) có tính private và protected của thành viên
Tính static
ClassB và ngược lại. Tính const

• Trong dự án, có một số hàm hoặc lớp cần cho các lớp Quan hệ bạn bè
Hàm bạn bè

khác truy xuất các thành viên (thuộc tính & phương Lớp bạn bè

Tổ chức mã nguồn
thức) có tính private và protected của nó. Vì lý do: cho các lớp
1 Code cho đơn giản.
2 Tránh gọi hàm nhiều lần.
3 Các lớp này được thiết kế cẩn thận và nằm trong cùng
dự án nên vẫn có thể kiểm soát sự toàn vẹn dữ liệu
được.
⇒ Cơ chế này được gọi là quan hệ bạn bè (friendship).

OOP (P.2).19
OOP (P.2)
Các dạng quan hệ bạn bè
ThS.
Trần Ngọc Bảo Duy

1 Hàm friend: Cho phép một hàm không phải thành Đặc tính đặc biệt của
viên của lớp ClassX vẫn có thể truy cập các thành thành viên
Tính static

viên (thuộc tính & phương thức) có tính private và Tính const

protected của ClassX. Quan hệ bạn bè


Hàm bạn bè
Lớp bạn bè

2 Lớp friend: Cho phép tất cả các phương thức thành Tổ chức mã nguồn
cho các lớp
viên của ClassY có thể truy cập các thành viên (thuộc
tính & phương thức) có tính private và protected của
ClassX.

OOP (P.2).20
OOP (P.2)
Hàm bạn bè
ThS.
Trần Ngọc Bảo Duy

Với lớp Complex, hãy bổ sung toán tử cộng/ trừ/ nhân Đặc tính đặc biệt của
thành viên
với số nguyên/ số thực, sao cho đoạn mã sau đây thực thi Tính static

thành công: Tính const

Quan hệ bạn bè
1 Complex a (1 , 2); Hàm bạn bè
Lớp bạn bè
2 Complex b = a + 1.2;
Tổ chức mã nguồn
3 Complex c = a + 2; cho các lớp
4 Complex d = 1.2 + a ;
5 Complex e = 2 + a;

OOP (P.2).21
OOP (P.2)
Hàm bạn bè
ThS.
Trần Ngọc Bảo Duy

1 Complex a (1 , 2);
2 Complex b = a + 1.2;
Đặc tính đặc biệt của
3 Complex c = a + 2; thành viên
4 Complex d = 1.2 + a ; Tính static
Tính const
5 Complex e = 2 + a;
Quan hệ bạn bè
Hàm bạn bè
Để dòng 2 - 3 thực thi thành công, ta chỉ cần định nghĩa Lớp bạn bè

thêm các phương thức sau đây: Tổ chức mã nguồn


cho các lớp
1 Complex operator +( const int & rhs );
2 Complex operator +( const double & rhs );
3 Complex operator +( const float & rhs );

vì lúc này, biến bên trái toán tử là thuộc lớp Complex.

OOP (P.2).22
OOP (P.2)
Hàm bạn bè
ThS.
Trần Ngọc Bảo Duy

1 Complex a (1 , 2);
2 Complex b = a + 1.2;
3 Complex c = a + 2; Đặc tính đặc biệt của
thành viên
4 Complex d = 1.2 + a ; Tính static

5 Complex e = 2 + a; Tính const

Quan hệ bạn bè
Tuy nhiên, để dòng 4 - 5 thì không thể dùng các định nghĩa Hàm bạn bè
Lớp bạn bè

này vì bên bên trái toán tử là thuộc kiểu int hoặc float Tổ chức mã nguồn
cho các lớp
hoặc double, ... Muốn vậy, ta phải thực hiện quá tải các
hàm (function overloading) nằm ngoài lớp Complex:
1 Complex operator +( int lhs , const Complex & rhs );
2 Complex operator +( double lhs , const Complex & rhs );
3 Complex operator +( float lhs , const Complex & rhs );

OOP (P.2).23
OOP (P.2)
Hàm bạn bè: Minh họa
ThS.
Trần Ngọc Bảo Duy

1 class Complex {
2 public :
3 Complex operator +( const double & rhs ) {
4 return Complex ( this - > real + rhs , this - > img ); Đặc tính đặc biệt của
thành viên
5 } Tính static
6 }; Tính const

7
Quan hệ bạn bè
8 Complex operator +( double lhs , const Complex & rhs ) { Hàm bạn bè
9 Complex res ; Lớp bạn bè

10 res . setReal ( lhs + rhs . getReal ()); Tổ chức mã nguồn


11 res . setImg ( rhs . getImg ()); cho các lớp
12 return res ;
13 }

Việc truy cập bằng các getter/setter như dòng 10 - 11 khá phức tạp
và dài dòng, nên ta có thể thiết lập hàm trên thành hàm bạn bè của
lớp Complex.

OOP (P.2).24
OOP (P.2)
Hàm bạn bè: Minh họa
ThS.
Trần Ngọc Bảo Duy

1 class Complex {
2 public :
3 Complex operator +( const double & rhs ) {
4 return Complex ( this - > real + rhs , this - > img ); Đặc tính đặc biệt của
5 } thành viên
6 Tính static
Tính const
7 friend Complex operator +( double lhs ,
8 const Complex & rhs ); Quan hệ bạn bè
9 }; Hàm bạn bè
Lớp bạn bè
10
11 Complex operator +( double lhs , const Complex & rhs ) { Tổ chức mã nguồn
cho các lớp
12 Complex res ;
13 res . real = lhs + rhs . real ;
14 res . img = rhs . img ;
15 return res ;
16 }

Nhờ thiết lập quan hệ bạn bè này, trong thân hàm (dòng 12 - 15) ta
có thể truy xuất các thành viên có tính private và protected.

OOP (P.2).25
OOP (P.2)
Nhập xuất với toán tử » và «
ThS.
Trần Ngọc Bảo Duy

Đặc tính đặc biệt của


thành viên

Để toán tử >> và << của cin và cout hoạt động trên lớp định Tính static
Tính const

nghĩa, ta sử dụng hàm bạn bè với prototype sau: Quan hệ bạn bè


Hàm bạn bè
ostream & operator < <( ostream & output , const Complex & c ); Lớp bạn bè

istream & operator > >( istream & output , const Complex & c ); Tổ chức mã nguồn
cho các lớp

OOP (P.2).26
OOP (P.2)
Lớp bạn bè
ThS.
Trần Ngọc Bảo Duy
Tương tự với hàm bạn bè, ta có thể định nghĩa lớp bạn bè
với công dụng cho phép lớp bạn truy xuất được các thành
viên có tính private và protected của ta.
Đặc tính đặc biệt của
Giả sử, số phức có các ứng dụng lớn trong ngành Kỹ thuật thành viên
Tính static
điện, người ta có thể giải các bài toán điện xoay chiều bằng Tính const

số phức. Ta có lớp điện áp Voltage để mô tả điện áp giữa Quan hệ bạn bè


Hàm bạn bè
hai điểm trên mạch điện xoay chiều: Lớp bạn bè

Tổ chức mã nguồn
1 class Voltage ; cho các lớp
2
3 class Complex {
4 public :
5 friend class Voltage ;
6 };
7 class Voltage {
8 Complex value ;
9 };

OOP (P.2).27
OOP (P.2)

ThS.
Trần Ngọc Bảo Duy

Đặc tính đặc biệt của


thành viên

TỔ CHỨC MÃ NGUỒN Tính static


Tính const

Quan hệ bạn bè

CHO CÁC LỚP Hàm bạn bè


Lớp bạn bè

Tổ chức mã nguồn
cho các lớp

OOP (P.2).28
OOP (P.2)
Tổ chức mã nguồn cho các lớp
ThS.
Trần Ngọc Bảo Duy

• Một lớp có nhiều hàm thành viên, phần thân những


hàm này có thể để chung với phần mô tả của lớp, như Đặc tính đặc biệt của
thành viên
ở các ví dụ trước. Tính static
Tính const

• Tuy vậy, thường các dự án lớn (đặc biệt là dạng thư Quan hệ bạn bè

viện phần mềm), mỗi lớp được tổ chức thành 2 tập tin Hàm bạn bè
Lớp bạn bè

riêng biệt: Tổ chức mã nguồn


cho các lớp
1 Tập tin header (*.h): Tập tin này chứa phần mô tả
(description, declaration) cho lớp.
2 Tập tin source (*.cpp): Tập tin này chứa phần định
nghĩa (definition) cho lớp.

OOP (P.2).29
OOP (P.2)
Tổ chức mã nguồn cho các lớp: Minh họa
ThS.
Trần Ngọc Bảo Duy
File Date.h: Chứa phần định nghĩa (hiện thực) cho lớp.
1 # ifndef DATE_H
2 # define DATE_H
3 class Date {
4 public : Đặc tính đặc biệt của
5 int getDay ( void ); thành viên
6 void setDay ( int newDay ); Tính static
Tính const
7 int getMonth ( void );
8 void setMonth ( int newMonth ); Quan hệ bạn bè
9 int getYear ( void ); Hàm bạn bè
Lớp bạn bè
10 void setYear ( int newYear );
11 int compareTo ( const Date & aDate ); Tổ chức mã nguồn
cho các lớp
12 int distanceTo ( const Date & aDate );
13 Date ();
14 Date ( const Date & oldDate );
15 void date ( int day , int month , int year );
16 private :
17 int day ;
18 int month ;
19 int year ;
20 };
21 # endif

OOP (P.2).30
OOP (P.2)
Tổ chức mã nguồn cho các lớp: Minh họa
ThS.
File Date.cpp: Chứa phần mô tả (khai báo) cho lớp. Trần Ngọc Bảo Duy
1 # include " Date . h "
2 int Date :: getDay ( void ){
3 return day ;
4 }
5 void Date :: setDay ( int newDay ){
Đặc tính đặc biệt của
6 day = newDay ; thành viên
7 } Tính static

8 int Date :: getMonth ( void ){ Tính const

9 return month ; Quan hệ bạn bè


10 } Hàm bạn bè
Lớp bạn bè
11 void Date :: setMonth ( int newMonth ){
12 month = newMonth ; Tổ chức mã nguồn
13 } cho các lớp

14 int Date :: getYear ( void ){


15 return year ;
16 }
17 void Date :: setYear ( int newYear ){
18 year = newYear ;
19 }
20
21 // Other methods

Dùng toán tử :: khi hàm định nghĩa bên ngoài phần mô tả của lớp. Các
hàm có tên đầy đủ có dạng: <Tên lớp>::<Tên hàm>. OOP (P.2).31

You might also like