Bài giảng Lập trình C/C++ - Chương 10: Lập trình hướng đối tượng (Cơ bản) - Lê Thành Sách

Nội dung

n Kiểu dữ liệu trong C - Ôn lại

n Các khái niệm cơ bản

n Con trỏ this

n Tổng hợp các thuật ngữ (I)

n Tính khả kiến

n Thiết kế lớp

n Hàm khởi tạo và hàm huỷ

n Định nghĩa lại toán tử

n Thành viên có tính “static”

n Thành viên có tính “const”

n Tổng hợp các thuật ngữ (II)

n Quan hệ bạn bè (friendship)

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

n Biễu diễn lớp bằng sơ đồ

n Tổng kết

pdf 117 trang phuongnguyen 8260
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Lập trình C/C++ - Chương 10: Lập trình hướng đối tượng (Cơ bản) - Lê Thành Sách", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

Tóm tắt nội dung tài liệu: Bài giảng Lập trình C/C++ - Chương 10: Lập trình hướng đối tượng (Cơ bản) - Lê Thành Sách

Bài giảng Lập trình C/C++ - Chương 10: Lập trình hướng đối tượng (Cơ bản) - Lê Thành Sách
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
1
Chương 10
Lập trình hướng đối tượng
--Cơ bản--
Lê Thành Sách
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
2
Nội dung
n Kiểu dữ liệu trong C - Ôn lại
n Các khái niệm cơ bản
n Con trỏ this
n Tổng hợp các thuật ngữ (I)
n Tính khả kiến
n Thiết kế lớp
n Hàm khởi tạo và hàm huỷ
n Định nghĩa lại toán tử
n Thành viên có tính “static”
n Thành viên có tính “const”
n Tổng hợp các thuật ngữ (II)
n Quan hệ bạn bè (friendship)
n Tổ chức mã nguồn cho lớp
n Biễu diễn lớp bằng sơ đồ
n Tổng kết
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
3
typedef struct{
int day, month, year;
} Date;
int main(int argc, char** argv) {
int a;
double d;
Date c = {20, 5, 2017};
return 0;
}
Kiểu dữ liệu trong C
n Xét đoạn chương trình
Bộ biên dịch cấp phát 3 vùng nhớ có 
tên: a, d, và c trên STACK:
a: 4 bytes à dùng sizeof(.) cho cụ thể.
d: 8 bytes
c: 12 bytes
Cả 3 vùng nhớ này đều THỤ ĐỘNG, 
CHỈ CÓ CÔNG NĂNG LÀ CHỨA các giá 
trị của kiểu được mô tả.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
4
Kiểu dữ liệu trong C
Vì thụ động, nên khi cần xử lý dữ liệu, thực hiện:
a) Tạo ra hàm
b) Gọi hàm và truyền dữ liệu vào à Ví dụ như hàm: “print” ở trên
typedef struct{
int day, month, year;
} Date;
void print(Date& d){
cout << d.day << "/" << d.month << "/" << d.year;
}
int main(int argc, char** argv) {
int a;
double d;
Date c = {20, 5, 2017};
print(c);
return 0;
}
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
5
Kiểu dữ liệu trong C
Vì thụ động, nên khi cần xử lý dữ liệu:
a) Tạo ra hàm
b) Gọi hàm và truyền dữ liệu vào à Ví 
dụ như hàm: print ở trên
Nhược điểm của tính THỤ 
ĐỘNG này là gì?
typedef struct{
int day, month, year;
} Date;
void print(Date& d){
cout << d.day << "/" << d.month << "/" << d.year;
}
int main(int argc, char** argv) {
int a;
double d;
Date c = {20, 5, 2017};
print(c);
return 0;
}
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
6
Kiểu dữ liệu trong C
n Nhược điểm là gì?
n Khó biết được dữ liệu có thể được xử lý bởi hàm nào.
n Khó đảm bảo ràng buộc trên dữ liệu, ví dụ:
n Ngày: 1 à 31 (tuỳ tháng, tối đa)
n Tháng: 1 à 12
Chỉ cần tính chất về “đóng gói” (enscapsulation) của lập trình hướng đối
tượng (OOP) đã giải quyết những vấn đề trên.
Hơn nữa, ngoài tính “đóng gói”, OOP còn cung cấp những tính năng hay
khác nữa mà ngôn ngữ C không có.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
7
Khái niệm cơ bản
n (Q.1) Lớp (class):
n Là một kiểu dữ liệu do người lập trình tạo ra.
n Quan niệm: Lớp như cái khuôn để từ đó tạo ra các đối tượng như 
nói sau.
n (Q.2) Đối tượng (object, instance):
n Là một biến tạo ra từ kiểu lớp.
n Ví dụ:
n Giả sử đã có lớp MyClass
n Dòng: 
MyClass c;
n Sẽ tạo ra một đối tượng, đặt tên là “c”, nghĩa là một vùng nhớ có 
tên là “c”.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
8
Khái niệm cơ bản
n (Q.3) Mô tả lớp có gì khác mô tả một cấu trúc trong C 
(struct)
n Khi mô tả kiểu này, cần mô tả
n Các dữ liệu mà một đối tượng của lớp có.
n Các hàm (phương thức) có thể thực thi với đối tượng của lớp.
n Những hành động mà một đối tượng của lớp đó có thể thực 
hiện à tính chủ động của đối tượng (không chỉ là vùng nhớ 
thụ động)
Với kiểu struct (của C):
Mô tả kiểu này không có mô tả hàm/phương thức như kiểu lớp!
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
9
Khái niệm cơ bản
n (Q.4) Tạo đối tượng như thế nào?
n Giống như struct. Giả sử có lớp MyClass
n (1) Tạo tĩnh trên STACK:
MyClass obj;
MyClass obj(); 
//có thể truyền tham số - xem Phần Constructor 
n (2) Tạo động trên HEAP:
MyClass *ptr = new MyClass();
MyClass *ptr = new MyClass(); 
//có thể truyền tham số - xem Phần Constructor
//dùng ptr tại đây
delete ptr;
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
10
Khái niệm cơ bản
n (Q.4) Tạo đối tượng như thế nào?
n Giống như struct. Giả sử có lớp MyClass
n (1) Tạo tĩnh trên STACK, mảng tĩnh
MyClass obj[SIZE];
n (2) Tạo động trên HEAP:
MyClass *ptr = new MyClass[SIZE];
//.. sử dụng ptr
delete []ptr;
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
11
Khái niệm cơ bản
n (Q.5) Truy xuất dữ liệu và gọi phương thức ntn?
n Giống như struct. Giả sử có lớp MyClass
n (1) đối tượng trên STACK:
MyClass obj;
...
obj.[tên-thành-viên]; //xem ví dụ.
n (2) đối tượng trên HEAP:
MyClass *ptr = new MyClass();
...
Obj->[tên-thành-viên]; //xem ví dụ.
Lưu ý:
Toán tử chấm “.” và toán tử mũi tên “->”
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
12
Khái niệm cơ bản: Minh hoạ (I)
n Tạo ra một kiểu “Date”, theo yêu cầu:
n Một đối tượng của “Date” có phải chứa được dữ liệu về ngày, 
tháng, và năm.
n Một đối tượng của “Date” có thể đón nhận lời yêu cầu “print”. Một 
khi nó (đối tượng) nhận được yêu cầu này, nó in ra màn hình ngày, 
tháng, và năm mà nó đang giữ.
n Đối tượng có tính CHỦ ĐỘNG hơn so với các biến kiểu cấu trúc 
(của C)
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
13
Khái niệm cơ bản: Minh hoạ (I)
class Date{
public:
int day, month, year;
void print(){
cout << day << "/" << month << "/" << year << endl;
}
};
Một lớp (class) “Date”
Chú ý: kết thúc bằng dấu ;
Mô tả dữ liệu cho đối tượng của lớp “Date”
Mô tả phương thức cho đối tượng của lớp “Date”:
khai báo + định nghĩa hàm
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
14
Khái niệm cơ bản: Minh hoạ (I)
class Date{
public:
int day, month, year;
void print(){
cout << day << "/" << month << "/" << year << endl;
}
};
Từ khoá “public” nghĩa là gì?
Cho phép bất kỳ nơi nào, miễn sao có tham chiếu đến đối tượng kiểu
“Date”, là có thể dùng được các dữ liệu và phương thức theo sau “public”,
i.e., day, month, year và print
Xem phần “Tính khả kiến” – theo sau.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
15
Khái niệm cơ bản: Minh hoạ (I)
int main(int argc, char** argv) { 
Date d1 = {20, 5, 2017};
Date d2 = {21, 5, 2017};
Date d3 = {22, 5, 2017};
d1.print();
d2.print();
d3.print();
return 0;
}
Dùng lớp “Date” như thế nào?
Xem hàm main() sau:
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
16
Khái niệm cơ bản: Minh hoạ (I)
int main(int argc, char** argv) { 
Date d1 = {20, 5, 2017};
Date d2 = {21, 5, 2017};
Date d3 = {22, 5, 2017};
d1.print();
d2.print();
d3.print();
return 0;
}
day:
month:
year:
20
5
2017
print
d1
day:
month:
year:
22
5
2017
print
d3
day:
month:
year:
21
5
2017
print
d2
Tạo ra 3 đối tượng 
có tên là d1, d2, 
và d3, 
và khởi gán giá trị 
ban đầu.
Lưu ý:
Đối tượng = dữ liệu + hàm
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
17
Lưu ý
Trong trường hợp như lớp “Date”, phương thức “print” không phải liên kết
động (vì: non-virtual) nên con trỏ hàm không cần đi kèm trong bộ nhớ cấp
cho đối tượng, xem hình.
Tuy nhiên, slide này trình bày mô hình như vậy để giúp sinh viên dễ dàng
nắm bắt khái niệm gói cả dữ liệu và hàm. Có thể xem đây là mô hình đơn
giản và ở mức cao (luận lý).
Người học nên xem thêm các tài liệu khác để nắm rõ hơn về mô hình đối
tượng (Object Model):
[1] Stanley B. Lippman, “Inside the C++ Object Model,” Addison Wesley,
1996.
[2] 
Tuy vậy, chỉ nên đọc sau khi nắm bắt chắc các khái niệm và cách
dùng OOP trong slide này.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
18
Khái niệm cơ bản: Minh hoạ (I)
int main(int argc, char** argv) { 
Date d1 = {20, 5, 2017};
Date d2 = {21, 5, 2017};
Date d3 = {22, 5, 2017};
d1.print();
d2.print();
d3.print();
return 0;
}
day:
month:
year:
20
5
2017
print
d1
class Date{
public:
int day, month, year;
void print(){
cout << day << "/" << month << "/" << year << endl;
}
};
Khi gọi hàm print của d1 thì:
day = 20;
month = 5;
Và year = 2017
Lưu ý:
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
19
Khái niệm cơ bản: Minh hoạ (I)
int main(int argc, char** argv) { 
Date d1 = {20, 5, 2017};
Date d2 = {21, 5, 2017};
Date d3 = {22, 5, 2017};
d1.print();
d2.print();
d3.print();
return 0;
}
Khi gọi hàm print của d2 thì:
day = 21;
month = 5;
Và year = 2017
Lưu ý:day:
month:
year:
21
5
2017
print
d2
class Date{
public:
int day, month, year;
void print(){
cout << day << "/" << month << "/" << year << endl;
}
};
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
20
day:
month:
year:
22
5
2017
print
d3
Khái niệm cơ bản: Minh hoạ (I)
int main(int argc, char** argv) { 
Date d1 = {20, 5, 2017};
Date d2 = {21, 5, 2017};
Date d3 = {22, 5, 2017};
d1.print();
d2.print();
d3.print();
return 0;
}
Khi gọi hàm print của d3 thì:
day = 22;
month = 5;
Và year = 2017
Lưu ý:
class Date{
public:
int day, month, year;
void print(){
cout << day << "/" << month << "/" << year << endl;
}
};
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
21
Khái niệm cơ bản: Minh hoạ (I)
int main(int argc, char** argv) { 
Date d1 = {20, 5, 2017};
Date d2 = {21, 5, 2017};
Date d3 = {22, 5, 2017};
d1.print();
d2.print();
d3.print();
return 0;
}
Kết quả xuất ra màn hình:
20/5/2017
21/5/2017
22/5/2017
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
22
Khái niệm cơ bản: Minh hoạ (I)
int main(int argc, char** argv) { 
Date d1 = {20, 5, 2017};
Date d2 = {21, 5, 2017};
Date d3 = {22, 5, 2017};
d1.print();
d2.print();
d3.print();
return 0;
}
class Date{
public:
int day, month, year;
void print(){
//đã rút gọn
}
};
Vì từ khoá “public” à day, month, year và print có thể 
truy cập được bất kỳ đâu.
è Truy cập được trong hàm main()
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
23
Con trỏ “this”
n Đối tượng = dữ liệu + hàm. Ví dụ:
n Địa chỉ đến (byte đầu tiên của) đối tượng được lưu trong 
biến “this” (là từ khoá). Địa chỉ này chỉ có thể dùng được 
bên trong các hàm thành viên của đối tượng.
n Bên trong print của d1: this chỉ đến vùng d1.
n Bên trong print của d2: this chỉ đến vùng d2, ...
day:
month:
year:
20
5
2017
print
d1
day:
month:
year:
21
5
2017
print
d2
day:
month:
year:
22
5
2017
print
d3
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
24
Con trỏ “this”: Minh hoạ (I)
class Date{
public:
int day, month, year;
void print(){
cout << day << "/" << month << "/" << year << endl;
}
};
class Date{
public:
int day, month, year;
void print(){
cout day month year << endl;
}
};
Hàm print có thể viết như sau:
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
25
Con trỏ “this”: Minh hoạ (II)
class Date{
public:
int day, month, year;
void print(){
//đã rút gọn
}
void setDay(int day){
}
};
Tại đây có hai biến cùng tên: day.
• day: của thông số
• Và, day là thành viên của lớp.
Mặc nhiên, day của thông số là ưu tiên.
Do đó, để gán day của thông số vào day
thành viên thì dùng “this”, như sau:
this->day = day;
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
26
Con trỏ “this”: Minh hoạ (III)
class Date{
public:
int day, month, year;
void print(){
//đã rút gọn
}
void setDay(int day){
this->day = day;
}
Date& getDate(){
}
};
Giả sử: cần trả về tham khảo đến đối tượng 
đang chứa hàm getDate
Làm như thế nào?
Dùng con trỏ “this”, như sau:
return *this;
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
27
Con trỏ “this”: Minh hoạ (IV)
class Date{
public:
int day, month, year;
void print(){
//đã rút gọn
}
void setDay(int day){
this->day = day;
}
Date& getDate(){
return *this;
}
Date* getDatePtr(){
}
};
Giả sử: cần trả về con trỏ đến đối tượng 
đang chứa hàm getDatePtr
Làm như thế nào?
Dùng con trỏ “this”, như sau:
return this;
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
28
Con trỏ “this”: Câu hỏi
class Date{
public:
int day, month, year;
void print(){
//đã rút gọn
}
void setDay(int day){
this->day = day;
}
Date& getDate(){
return *this;
}
Date* getDatePtr(){
return this;
}
};
int main(){
Date d;
cout << ”ptr1:" << hex << &d << endl;
cout << ”ptr2: " << hex <<
d.getDatePtr() << endl;
return 0;
}
Giá trị in ra chỗ ptr1 và ptr2 có bằng nhau?
CuuDuongThanCong.com https://fb.com/tailieudientucn ... 
int rs;
rs = const_value + nonconst_value;
//const_value = 100;
//nonconst_value = 100;
mutable_value = 100;
rs += mutable_value;
return rs;
}
};
Nếu hai dòng này được biên
dịch à lỗi biên dịch.
Lý do: phương thức có tính
hằng chỉ có thể thay đổi biến có
tính “mutable”.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
94
Thuật ngữ (II)
n Tổng kết các khái niệm quan trọng:
Tiếng việt Tiếng Anh Chú thích
Lớp class Xem như một kiểu dữ liệu
Đối tượng Object, instance Xem như một biến
Thuộc tính;
Biến thành viên;
Trường dữ liệu;
Thành viên dữ liệu
Attribute;
Member variable;
Data field;
Data member Dữ liệu + Phương thức 
được gói lại thành đối tượng
(gói dữ liệu và địa chỉ hàm)Phương thức;
Hàm thành viên;
Hành xử;
Hành động
Method;
Function member;
Behavior;
operation
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
95
Thuật ngữ (II)
n Tổng kết các khái niệm quan trọng:
Tiếng việt Tiếng Anh Chú thích
Tính khả kiến Visibility Cho biết một thuộc tính & phương 
thức có thể dùng được ở đâu 
trong mã nguồn (lớp nào, phương 
thức nào, hàm nào?)
Ba tính khả kiến: 
public, private, và 
protected
public, private, và 
protected
public: mọi nơi
private: của riêng
protected: của riêng + dành cho 
con và cháu.
Hàm đọc dữ liệu getter Nên:
• Các thuộc tính có tính khả kiến 
là: private
• Mỗi thuộc tính nên kèm theo 
01 getter và 01 setter.
Hàm ghi dữ liệu setter
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
96
Thuật ngữ (II)
n Tổng kết các khái niệm quan trọng:
Tiếng việt Tiếng Anh Chú thích
từ khoá “this” this this: có kiểu là địa chỉ.
this: chứa địa chỉ đến byte đầu 
tiên của vùng nhớ của đối tượng.
this: chỉ được nhìn thấy bên trong 
các hàm thành viên.
è
this->data_member;
this->foo();
với:
data_member: thuộc tính
foo(): một phương thức của đối 
tượng.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
97
Thuật ngữ (II)
n Tổng kết các khái niệm quan trọng:
Tiếng việt Tiếng Anh Chú thích
Hàm khởi tạo copy Copy constructor Khi biến thành viên được cấp 
phát động (như ma trận ở slide 
trước)
CẦN PHẢI:
èĐịnh nghĩa lại cả “copy 
contructor” và “copy 
assignment”
Phép gán Copy assignment
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
98
Quan hệ bạn bè (friendship)
n Giả sử lớp ClassA và ClassB là hai lớp độc lập, không có 
quan hệ thừa kế (sẽ trình bày sau)
n 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 (biến & hàm) có tính private và protected của ClassB và 
ngược lại.
n Trong dự án có một số lớp cần cho các lớp khác truy xuất 
các thành viên (biến & hàm) có tính private và protected
của nó. Vì lý do:
n Code cho đơn giản.
n Tránh gọi hàm nhiều lần à chạy nhanh hơn.
n 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.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
99
Quan hệ bạn bè (friendship)
n Các dạng friendship
n Hàm friend
n Cho phép một hàm không phải thành viên của lớp ClassX vẫn 
có thể truy cập các thành viên (biến & hàm) có tính private và 
protected của ClassX.
n Lớp friend
n Cho phép tất cả các hàm thành viên của ClassY có thể truy cập 
các thành viên (biến & hàm) có tính private và protected của 
ClassX.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
100
Quan hệ bạn bè (friendship): Minh hoạ (I)
n Hàm friend:
n Với lớp Matrix ở các slide trước, hãy bổ sung code để cho phép 
người lập trình có thể thực hiện các phép toán sau:
n Cho phép người lập trình nhập và xuất ma trận bằng các toán 
tử: >
n Cộng/trừ/nhân/chia một số vô hướng (số thực, double) với ma 
trận, như ví dụ sau. Ý nghĩa của các phép toán này là thực hiện 
phép toán đó giữa số vô hướng với từng phần tử của ma trận
double data[] = {1,2,3,4,5,6};
Matrix m1(2,3, data, 6);
Matrix m2, m3, m4;
m2 = 3.5 + m1;
m3 = 3.5 - m1;
m4 = 3.5 * m1;
m5 = 3.5 / m1;
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
101
Quan hệ bạn bè (friendship): Minh hoạ (I)
n Phân tích:
n Prototype của các toán tử như sau:
n Với dạng protoype như vậy, chúng không thể là hàm thành viên của 
lớp Matrix.
n Nhưng, chúng ta truy xuất các dữ liệu: số hàng, số cột, và dữ liệu 
(có tính private) của Matrix
n è Dùng Hàm friend
§ ostream &operator<<( ostream &output, const Matrix& matrix);
§ istream &operator>>( istream &input, Matrix& matrix);
§ Matrix operator+(double value, const Matrix& matrix);
§ Matrix operator-(double value, const Matrix& matrix);
§ Matrix operator*(double value, const Matrix& matrix);
§ Matrix operator*(double value, const Matrix& matrix);
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
102
Quan hệ bạn bè (friendship): Minh hoạ (I)
class Matrix{
public:
friend ostream &operator<<( ostream &output, 
const Matrix& matrix);
friend istream &operator>>( istream &input, Matrix& matrix);
friend Matrix operator+(double value, const Matrix& matrix);
friend Matrix operator-(double value, const Matrix& matrix);
friend Matrix operator*(double value, const Matrix& matrix);
friend Matrix operator*(double value, const Matrix& matrix);
// Các hàm thành viên khác, xem các slide trước.
private:
double *m_data_ptr;
int m_nrows, m_ncols;
};
Khai báo hàm (toán tử) friend
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
103
Quan hệ bạn bè (friendship): Minh hoạ (I)
istream &operator>>( istream &input, Matrix& matrix){
// Các lệnh nhập dữ liệu tại đây
return input;
}
Định nghĩa toán tử >>
ostream &operator<<( ostream &output, const Matrix& matrix){
// Các lệnh xuất dữ liệu tại đây
return output;
}
Định nghĩa toán tử <<
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
104
Quan hệ bạn bè (friendship): Minh hoạ (I)
Matrix operator+(double value, const Matrix& matrix){
Matrix rs = matrix;
//Cộng các phần tử của rs với value, gán lại vào rs.
return rs;
}
Matrix operator-(double value, const Matrix& matrix){
Matrix rs = matrix;
//Trừ value cho các phần tử của rs, gán lại vào rs.
return rs;
}
Định nghĩa toán tử + và –
Các toán tử * và / tương tự.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
105
Quan hệ bạn bè (friendship): Minh hoạ (II)
n Lớp friend:
n Với lớp Matrix ở các slide trước, giả sử cần thiết kế lớp xử lý dữ 
liệu (DataProcessor).
n Lớp DataProcessor có nhiều hàm thành viên, chúng cần lưu dữ liệu 
dưới dạng ma trận, và chúng cần truy xuất dữ liệu của ma trận (số 
hàng, số cột, và dữ liệu các phần tử).
n => Có thể sử dụng lớp friend để cho phép tất cả các phương 
thức trong DataProcessor truy xuất được các dữ liệu liệu của 
ma trận (có tính private).
n Khai báo lớp DataProcessor là friend của lớp Matrix như sau.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
106
Quan hệ bạn bè (friendship): Minh hoạ (I)
Class DataProcessor; //Khai báo trước cho lớp DataProcessor
class Matrix{
public:
friend class DataProcessor;
friend ostream &operator<<( ostream &output, 
const Matrix& matrix);
friend istream &operator>>( istream &input, Matrix& matrix);
friend Matrix operator+(double value, const Matrix& matrix);
// Các hàm thành viên khác, xem các slide trước.
private:
double *m_data_ptr;
int m_nrows, m_ncols;
};
Khai báo lớp friend
Chú ý cả dòng khai báo trước cho lớp DataProcessor à để danh hiệu 
DataProcessor được biết là một lớp
Lớp DataProcessor: không có gì đặc biệt khi kết hợp vói friend
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
107
Tổ chức mã nguồn cho các lớp
n 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ác ví 
dụ trước.
n Tuy vậy, thường các dự án lớn (đặc biệt là dạng thư viện 
phần mềm), mỗi lớp được tổ chức thành 2 tập tin riêng biệt:
n Tập tin header (*.h):
n Tập tin này chứa phần mô tả (description, declaration) cho 
lớp
n Tập tin source (*.cpp): 
n Tập tin này chứa phần định nghĩa (definition) cho lớp
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
108
Tổ chức mã nguồn: Minh hoạ
#ifndef DATE_H
#define DATE_H
class Date{
public:
int getDay(void);
void setDay(int newDay);
int getMonth(void);
void setMonth(int newMonth);
int getYear(void);
void setYear(int newYear);
int compareTo(const Date& aDate);
int distanceTo(const Date& aDate);
Date();
Date(const Date& oldDate);
void date(int day, int month, int year);
private:
int day;
int month;
int year;
};
#endif
Date.h
Date.h:
Chứa phần mô tả (khai báo) 
cho lớp
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
109
#include "Date.h"
int Date::getDay(void){
return day;
}
void Date::setDay(int newDay){
day = newDay;
}
int Date::getMonth(void){
return month;
}
void Date::setMonth(int newMonth){
month = newMonth;
}
int Date::getYear(void){
return year;
}
void Date::setYear(int newYear){
year = newYear;
}
Tổ chức mã nguồn: Minh hoạ
Date.cpp - PART I
Date.cpp:
Chứa phần định nghĩa (definition) cho lớp
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 đủ là:
::
Như ví dụ:
Date::setDay
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
110
Tổ chức mã nguồn: Minh hoạ
int Date::compareTo(const Date& aDate){
// TODO : implement
}
int Date::distanceTo(const Date& aDate){
// TODO : implement
}
Date::Date(){
}
Date::Date(const Date& oldDate){
day = oldDate.day;
month = oldDate.month;
year = oldDate.year;
}
Date::Date(int day, int month, int year){
// TODO : implement
}
Date.cpp - PART II
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
111
Biễu diễn lớp bằng sơ đồ
Các thuộc tính, mỗi thuộc tính kiểu kèm theo, bên phải
• Ký hiệu ổ khoá (+): tính private
• Ký hiệu chìa khoá (-): tính protected
• Để trống (#): tính public 
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
112
Biễu diễn lớp bằng sơ đồ
Các hàm thành viên, mỗi hàm có 3 cột
• Cột trái: thông tin bổ sung, ví dụ: setter/getter, constructor
• Cột tên hàm và danh sách thông số
• Cột kiểu trả về
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
113
Biễu diễn lớp bằng sơ đồ
Thông tin từ hình ảnh là tương đương với thông tin của tập tin header.
Từ hình ảnh có thể sinh ra hai tập tin header và source tương ứng, chỉ có
một số hàm là có thể sinh ra được phần thân, như: setter/getter và
constructors
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
114
Tổng kết
n Hướng đối tượng là một phương pháp để phát triển ứng 
dụng có nhiều ưu điểm:
n Dễ cho thiết kế, viết mã, bảo trì và nâng cấp
n Dễ cho quản lý dự án khi quy mô của nó lớn
n Nhược điểm:
n Khó hiểu lúc bắt đầu
n Điểm quan trọng trong phần vừa qua:
n (1) Quan điểm về đối tượng:
n Đối tượng có tính chủ động.
n Nó chứa dữ liệu riêng
n Nó có thể đón nhận thông điệp (gọi hàm) từ các đối tượng khác.
n (2) Thời gian sống của đối tượng:
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
115
Tổng kết
n Điểm quan trọng trong phần vừa qua:
n (2) Thời gian sống của đối tượng:
n Từ thời điểm nó sinh ra: 
n Hàm khởi tạo luôn luôn được gọi tại thời điểm này
n Đến thời điểm nó bị huỷ (ra khỏi tầm vực hoặc bị delete)
n Hàm huỷ luôn luôn được gọi tại thời điểm này.
n (3) Trong thời gian nó sống (lưu trong bộ nhớ)
n Các đối tượng khác có thể gửi thông điệp (gọi hàm) đến nó.
n Nó thực thi hàm được gọi, có thể tạo ra các đối tượng khác 
và nhờ các đối tượng khác thực hiện một phần việc.
n Thiết kế tốt: ít khi cho các đối tượng khác trực tiếp truy xuất dữ 
liệu của đối tượng đang giữ mà không thông qua các phương 
thức.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
116
Tổng kết
n Điểm quan trọng trong phần vừa qua:
n (6) Phương pháp lập trình hướng đối tượng có tính trừu tượng hoá 
cao (abstraction).
n Hãy dùng tính khả kiến để che đi các phương thức hỗ trợ nội bộ 
và che đi dữ liệu nội bộ trong lớp.
n Hãy chỉ chia sẽ ra bên ngoài những phương thức chọn lọc thực 
sự phù hợp với lớp đang được thiết kế.
n à Người bắt đầu học về lập trình hướng đối tượng gặp khó 
khăn trong nguyên tắc thiết này à luyện tập dần dần.
n (7) Biểu diễn các lớp bằng sơ đồ giúp việc nắm bắt toàn bộ dự án 
dễ dàng hơn.
n Người bắt đầu có thể chưa quen.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Trường Đại Học Bách Khoa Tp.HCM
Khoa Khoa học và Kỹ thuật Máy tính
© 2017
Lập trình C/C++
117
Tổng kết
n Điểm quan trọng trong phần vừa qua:
n (4) Quan niệm về lớp vs đối tượng
n Lớp (class) như cái khuôn
n Còn đối tượng như những cái bánh tạo với khuôn đó.
n Dĩ nhiên, khuôn tròn, bánh không thể méo!
n (5)Tổ chức mã nguồn tốt, sẽ
n Tách riêng phần khai báo (hay mô tả) lớp vào một tập tin (*.h)
n Tách riêng phần định nghĩa các phương thức vào tập tin hiện 
thực (*.cpp)
n Module *.cpp (file cpp) phụ thuộc vào module *.h của chính lớp 
đó à dùng #include.
CuuDuongThanCong.com https://fb.com/tailieudientucntt

File đính kèm:

  • pdfbai_giang_lap_trinh_cc_chuong_10_lap_trinh_huong_doi_tuong_c.pdf