Bài giảng Ngôn ngữ lập trình C và C+ - Bài 6: Cấu trúc và Lớp - Đỗ Đăng Khoa

Một tập hợp của một hoặc nhiều biến, có thể khác kiểu nhau,

được nhóm lại dưới một tên duy nhất cho tiện xử lý

Trong các ứng dụng về cơ sở dữ liệu, kiểu cấu trúc còn được

gọi là bản ghi

Việc định nghĩa cấu trúc sẽ tạo ra kiểu dữ liệu mới

Ví dụ:

Hồ sơ nhân viên: mỗi nhân viên được mô tả bởi một tập các

thuộc tính như: tên, địa chỉ, số CMT, lươngM. Một trong số các

thuộc tính này lại có thể là một cấu trúc: tên có thể có vài thành

phần (họ, tên đệm, tên), địa chỉ và lương cũng có thể như vậy

Tài khoản ngân hàng: tên chủ tài khoản, tên tài khoản, số dư

tài khoản, loại tiề

pdf 63 trang yennguyen 5960
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Ngôn ngữ lập trình C và C+ - Bài 6: Cấu trúc và Lớp - Đỗ Đăng Khoa", để 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 Ngôn ngữ lập trình C và C+ - Bài 6: Cấu trúc và Lớp - Đỗ Đăng Khoa

Bài giảng Ngôn ngữ lập trình C và C+ - Bài 6: Cấu trúc và Lớp - Đỗ Đăng Khoa
5/12/2015
1
TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
Ngôn ngữ lập trình C và C++
Bài 6: Cấu trúc và Lớp
TS. Đỗ Đăng Khoa
Bộ môn Cơ học Ứng dụng
Viện Cơ khí
5/12/2015
2
Khái niệm về Cấu trúc (Struct)
Một tập hợp của một hoặc nhiều biến, có thể khác kiểu nhau, 
được nhóm lại dưới một tên duy nhất cho tiện xử lý
Trong các ứng dụng về cơ sở dữ liệu, kiểu cấu trúc còn được
gọi là bản ghi
Việc định nghĩa cấu trúc sẽ tạo ra kiểu dữ liệu mới
Ví dụ:
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Hồ sơ nhân viên: mỗi nhân viên được mô tả bởi một tập các
thuộc tính như: tên, địa chỉ, số CMT, lươngM. Một trong số các
thuộc tính này lại có thể là một cấu trúc: tên có thể có vài thành
phần (họ, tên đệm, tên), địa chỉ và lương cũng có thể như vậy
Tài khoản ngân hàng: tên chủ tài khoản, tên tài khoản, số dư
tài khoản, loại tiền
5/12/2015
3
Khai báo cấu trúc
Khai báo một cấu trúc
struct 
{ 
các thành phần ;
} ;
Ví dụ: 
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
struct point {
int x;
int y;
}a,b,c;
5/12/2015
4
Khai báo cấu trúc
Mỗi thành phần giống như một biến riêng của kiểu, nó gồm
kiểu và tên thành phần. Một thành phần cũng còn được gọi là
trường. 
Phần tên của kiểu cấu trúc và phần danh sách biến cấu trúc có
thể có hoặc không. Tuy nhiên trong khai báo kí tự kết thúc cuối
cùng phải là dấu chấm phẩy (;).
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Các kiểu cấu trúc được phép khai báo lồng nhau, nghĩa là một
thành phần của kiểu cấu trúc có thể lại là một trường có kiểu cấu
trúc.
Một biến có kiểu cấu trúc sẽ được phân bố bộ nhớ sao cho các
thực hiện của nó được sắp liên tục theo thứ tự xuất hiện trong
khai báo.
5/12/2015
5
Khai báo biến kiểu cấu trúc
Khai báo ngay sau dấu ngoặc }, danh sách các biến;
struct { ... } x, y, z;
Khai báo như biến thông thường (trong C)
struct 
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Khai báo như biến thông thường (trong C++) 
 ;
5/12/2015
6
Khởi tạo biến cấu trúc
Khởi tạo ngay định nghĩa của nó với danh sách các khởi tạo
cho các thành phần
point pt = {10, 20};
Sử dụng toán tử gán
point pt1 = {10, 20}, pt2;
pt2 = pt1;
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Ví dụ:
struct rect { 
point p1,p2;
};
rect rect1={{1,2},{3,4}};
5/12/2015
7
Truy cập đến thành phần của cấu trúc
Biến không phải con trỏ
tên_cấu_ trúc.thành_phần
Biến con trỏ:
tên_cấu_ trúc->thành_phần,
(*tên_cấu_trúc).thành_phần
Ví dụ: 
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
In tọa độ điểm pt:
printf("%d,%d", pt.x, pt.y);
//Tính khoảng cách từ pt đến tọa độ:
Double dist = sqrt((double)pt.x * pt.x + 
(double)pt.y * pt.y);
5/12/2015
8
Cấu trúc lồng nhau
Hình chữ nhật là một cặp điểm xác định hai góc đối diện.
struct rect {
point pt1;
point pt2;
};
Nếu khai báo screen là
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
rect screen;
thì
screen.pt1.x
chỉ đến tọa độ x của thành phần pt1 của screen.
5/12/2015
9
Hàm và Cấu trúc
Các thao tác hợp lệ duy nhất với một cấu trúc là
 Sao chép nó hoặc gán cho nó,
 Lấy địa chỉ qua &, 
Truy xuất các thành phần của nó.
Việc sao chép và gán bao gồm
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
 Truyền đối số tới hàm
Trả giá trị từ hàm
5/12/2015
10
Hàm và Cấu trúc
Hàm trả về một cấu trúc
là một biến cấu trúc.
là một con trỏ cấu trúc. 
là một tham chiếu cấu trúc.
 Ví dụ hàm trả về biến cấu trúc
struct Sophuc// Khai báo kiểu số phức dùng chung
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
{
float thuc; 
float ao; 
};
5/12/2015
11
Hàm và Cấu trúc
Sophuc Cong(Sophuc x, Sophuc y)
{
Sophuc kq;
kq.thuc = x.thuc + y.thuc ;
kq.ao = x.ao + y.ao ;
return kq;
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
}
void In(Sophuc x)
{
cout << "(" << x.thuc << "," << x.ao << ")" << 
endl ;
}
5/12/2015
12
Hàm và Cấu trúc
void main(){
Sophuc x, y;
cout > x.thuc >> x.ao ;
cout > y.thuc >> y.ao ;
cout << "x + y = " ; In(Cong(x,y)) ;}
Ví dụ hàm trả về con trỏ cấu trúc
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Sophuc* Tru(Sophuc x, Sophuc y){
Sophuc* kq=new Sophuc;
kq->thuc = x.thuc + y.thuc ;
kq->ao = x.ao + y.ao ;
return kq;
}
5/12/2015
13
Hàm và Cấu trúc
Hàm có đối số là cấu trúc
Là một biến cấu trúc
Là một con trỏ cấu trúc
Là một tham chiếu cấu trúc
Là một mảng cấu trúc hình thức hoặc con trỏ mảng
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Trường hợp cấu trúc lớn, sử dụng con trỏ và tham chiếu sẽ hiệu
quả hơn việc phải sao chép cả cấu trúc.
Con trỏ cấu trúc tương tương tự như con trỏ tới các biến thông
thường.
5/12/2015
14
Bảng (Mảng) Cấu trúc
Khai báo: 
struct_name {} tenbang[kích_thước];
struct_name tenbang[kích_thước];
Khởi tạo:
M = {,,,} hoặc ..={{,,},{,,},M}
Truy cập:
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
tenbang[i]
Ví dụ:
//mảng mười biến kiểu point
point a[10];
5/12/2015
15
Con trỏ Cấu trúc
Khai báo: 
struct_name * ten_con_tro;
Khởi gán thông qua phép lấy địa chỉ &
Ví dụ:
point p1={1,2}, *p2;
p2=&p1;
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Cấp phát động và thu hồi bộ nhớ cũng thông qua:
new và delete
Ví dụ:
point *p1=new point; delete p1;
int n=10;
point *p2=new point[n]; delete []p2;
5/12/2015
16
Kiểu Hợp
Kiểu hợp cũng có nhiều thành phần giống kiểu cấu trúc
Tuy nhiên, các thành phần của chúng sử dụng chung nhau một
vùng nhớ
Kích thước của một kiểu hợp là độ dài của trường lớn nhất và
việc
Thay đổi giá trị một thành phần sẽ ảnh hưởng đến tất cả các
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
thành phần còn lại
Ví dụ:
union { 
Danh sách các thành phần; 
}; 
5/12/2015
17
Truy cập đến thành phần của hợp
Biến không phải con trỏ
tên_cấu_ trúc.thành_phần
Biến con trỏ:
tên_cấu_ trúc->thành_phần,
(*tên_cấu_trúc).thành_phần
Ví dụ: 
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
union foo { int x; int y; };
foo f; f.x = 10;
/* cũng mang giá trị 10 vì dùng chung bộ nhớ với
f.x */
printf("%d\n", f.y);
5/12/2015
18
Từ Khóa typedef
Một kiểu dữ liệu có thể được định nghĩa bằng cách sử
dụng từ khóa typedef
Nó không tạo ra một kiểu dữ liệu mới, mà định nghĩa
một tên mới cho một kiểu đã có.
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Cú pháp: typedef type tên;
Ví dụ: typedef float deci;
5/12/2015
19
Lập trình hướng đối tượng
Đối tượng: là một đơn vị đầy đủ được kết hợp bởi các
dữ liệu và chỉ thị
Đối tượng được chia thành hai thành phần: các
phương thức (hàm) và các thuộc tính (biến)
Phương thức: là phương tiện để sử dụng đối tượng, 
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
trong khi các thuộc tính sẽ mô tả đối tượng có tính chất
gì
Đối tượng được trừu tượng hóa qua việc định nghĩa
của các lớp
5/12/2015
20
Các đặc tính của lập trình hướng đối tượng
Tính trừu tượng (abstraction):
Bỏ qua một số khía cạnh thông tin, chỉ tập trung vào những
cốt lõi cần thiết
Mỗi đối tượng có thể hoàn tất các công việc một cách nội 
bộ, báo cáo, thay đổi trạng thái của nó và liên lạc với các đối 
tượng khác, không cần cho biết làm cách nào tiến hành 
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
được các thao tác (trừu tượng dự liệu)
Tính trừu tượng còn thể hiện qua việc một đối tượng ban 
đầu có thể có một số đặc điểm chung cho nhiều đối tượng 
khác như là sự mở rộng của nó nhưng bản thân đối tượng 
này có thể không có các biện pháp thi hành (lớp trừu tượng
hay lớp cơ sở)
5/12/2015
21
Các đặc tính của lập trình hướng đối tượng
Tính đóng gói (encapsulation) và che giấu thông tin 
(information hiding):
Tính chất này không cho phép người sử dụng các đối tượng 
thay đổi trạng thái nội tại của một đối tượng
Chỉ có các phương thức nội tại của đối tượng cho phép thay 
đổi trạng thái của nó
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Tính đa hình (polymorphism): 
Thông qua việc gửi các thông điệp (message)
Các phương thức dùng trả lời cho một thông điệp sẽ tùy theo 
đối tượng mà thông điệp đó được gửi tới sẽ có phản ứng 
khác nhau
5/12/2015
22
Các đặc tính của lập trình hướng đối tượng
Tính kế thừa (inheritance):
Cho phép một đối tượng có thể có sẵn các đặc tính mà đối 
tượng khác đã có thông qua kế thừa
Cho phép các đối tượng chia sẻ hay mở rộng các đặc tính 
sẵn có mà không phải tiến hành định nghĩa lại
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Không phải ngôn ngữ hướng đối tượng nào cũng có tính 
chất này.
5/12/2015
23
Khái niệm về lớp (Class)
Một lớp bao gồm các hàm và dữ liệu có liên quan
Các hàm này là các hàm thành phần (member 
function) hay còn là phương thức (method)
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Giống như cấu trúc, lớp có thể xem như một kiểu dữ
liệu
Từ một lớp có thể tạo ra (bằng cách khai báo) nhiều
đối tượng (biến, mảng) khác nhau. Mỗi đối tượng có
vùng nhớ riêng của mình
5/12/2015
24
Khai báo lớp (Class)
Cú pháp:
class tên_lớp {
ñặc_tả_truy_cập_1:
member1;
ñặc_tả_truy_cập_2:
member2;
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
...
}danh_sách_ñối_tượng;
Ví dụ: class CRectangle {
int x, y;
public:
int area (void);} rect;
5/12/2015
25
Khai báo lớp (Class)
Việc khai báo một lớp không chiếm giữ bộ nhớ, chỉ các
đối tượng của lớp mới thực sự chiếm giữ bộ nhớ.
Thuộc tính của lớp có thể là các biến, mảng, con trỏ có
kiểu chuẩn (int, float, char, char*, long,...)
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Thuộc tính của lớp có thể là kiểu ngoài chuẩn đã định
nghĩa trước (struct, union, class,...)
Thuộc tính của lớp không thể có kiểu của chính lớp đó, 
nhưng có thể là con trỏ của lớp này
5/12/2015
26
Khai báo lớp (Class)- Các đặc tả truy cập
Các đặc tả truy cập này thay đổi các quyền truy cập
mà các thành phần khai báo sau chúng có được:
private: chỉ có thể truy cập từ bên trong thành phần
cùng lớp đó (trong thân các phương thức của lớp)
hoặc từ các thành phần bạn (friend) của nó.
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
protected: như private, ngoài ra còn từ các thành
phần của các lớp dẫn xuất (lớp con) của lớp đó.
public: có thể truy cập từ mọi nơi mà đối tượng hiển
thị.
Mặc định của class là quyền truy cập private đối với
tất cả thành phần của nó
5/12/2015
27
Khai báo lớp (Class)- Các đặc tả truy cập
Nếu các thành phần dữ liệu đã khai báo là private thì
các hàm thành phần phải có ít nhất một vài hàm được
khai báo dạng public để có thể truy cập được, nếu không
toàn bộ lớp sẽ bị đóng kín và điều này không giúp gì cho
chương trình
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Cách khai báo lớp tương đối phổ biến là các thành
phần dữ liệu được ở dạng private và hàm thành phần
dưới dạng public
5/12/2015
28
Khai báo lớp (Class)- Dữ liệu thành phần
Khai báo như khai báo các thành phần trong kiểu cấu
trúc hay hợp
Bình thường được khai báo là private để bảo đảm tính
giấu kín, bảo vệ an toàn dữ liệu của lớp không cho phép
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
các hàm bên ngoài xâm nhập vào các dữ liệu này.
Không được khai báo là auto, register hoặc extern
Kiểu: enum, kiểu dữ liệu có sẵn (chuẩn) hoặc người
dùng định nghĩa (struct, union, class)
5/12/2015
29
Khai báo lớp (Class)- Hàm thành phần
Hàm thành phần dùng để truy cập có kiểm soát vào thành
phần dữ liệu của lớp
Thường khai báo là public để chúng có thể được gọi tới
(sử dụng) từ các hàm khác trong chương trình
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Hàm khai báo là private chỉ có thể được gọi bởi các hàm
public khác trong lớp
Bản mẫu hàm: được khai báo bên trong phần thân lớp.
5/12/2015
30
Định nghĩa lớp (Class)- Hàm thành phần
Định nghĩa hàm: có thể được triển khai luôn trong thân lớp
hoặc bên ngoài lớp cùng toán tử phạm vi ::
(kiểu_trả_về tên_lớp::tên_hàm())
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Hàm được định nghĩa bên trong lớp sẽ được tự động coi
là hàm thành phần inline bởi trình biên dịch
Hàm thành phần được phép truy xuất tới các dữ liệu thành
phần, kể cả dữ liệu kiểu private
5/12/2015
31
Định nghĩa lớp (Class)- Hàm thành phần
Ví dụ:
#include 
#include 
class point{
private:
int x, y, m ; 
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
public:
void inputdata() ; 
void displaypoint() ; //Hiện một ñiểm
//Ẩn một ñiểm, hàm ñịnh nghĩa trong khai báo
void hidepoint() { putpixel(x, y,getbkcolor());
} }; 
5/12/2015
32
Định nghĩa lớp (Class)- Hàm thành phần
void point::inputdata(){
cout <<"\n Nhap hoanh do va tung do cua
diem:”; 
cin >> x >> y ; 
cout << “\n Nhap ma mau cua diem: “; 
cin >> m ; }
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
void point::displaypoint(){
int mau_ht ; 
mau_ht = getcolor(); 
putpixel(x, y, m);
setcolor(mau_ht); }
5/12/2015
33
Phạm vi lớp
Ngoài hai phạm vi toàn cục và cục bộ, C++ đưa ra khái
niệm về phạm vi lớp
Mọi thành phần của lớp được gọi là trong phạm vi của
lớp đó
Mọi thành phần của lớp đều có thể tham khảo tới bất kì
thành phần nào khác của cùng lớp
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Các hàm thành phần của lớp có quyền truy cập không
hạn chế vào thành phần dữ liệu của lớp đó
Việc truy cập vào các thành phần dữ liệu và hàm từ
ngoài phạm vi lớp do người lập trình kiểm soát
5/12/2015
34
Đối tượng, Mảng và con trỏ đối tượng của 
lớp
Một đối tượng (object) là một thể nghiệm của lớp  Lớp
là một định nghĩa của đối tượng.
Chú ý: Lớp là một kiểu dữ liệu, đối tượng của lớp này chỉ
là một biến.
Ví dụ:
point a;
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Cách khai báo mảng đối tượng, con trỏ đối tượng cũng
giống như khai báo biến, mảng các kiểu khác (như int, 
float, struct, union,...)
Ví dụ:
point b[10], *c;
c= new point;
5/12/2015
35
Truy xuất thuộc tính của đối tượng
Mỗi thuộc tính đều thuộc về một đối tượng, không thể viết tên
thuộc tính một cách riêng rẽ mà bao giờ cũng phải có tên đối
tượng đi kèm
Truy xuất thuộc tính của đối tượng bằng toán tử chấm .
tên_đối_tượng.Tên_thuộc_tính
con_trỏ_đối_tượng->Tên_thuộc_tính
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Ví dụ:
point a,*b;
a.x;// chỉ dùng ñược trong hàm thành phần
b=&a; b->y; // chỉ dùng ñược trong hàm thành phần
Chỉ có thể truy xuất thuộc tính private của đối tượng bằng các
hàm thành phần
5/12/2015
36
Sử dụng hàm thành phần của đối tượng
Cũng giống như hàm thông thường, hàm thành phần được
sử dụng thông qua lời gọi.
 Tuy nhiên trong lời gọi hàm thành phần bao giờ cũng phải có
tên đối tượng để chỉ rõ hàm thực hiện trên các thuộc tính của
đối tượng nào. 
Ví dụ:
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
void main(){
point a;
a.inputdata();
}
5/12/2015
37
Đối của hàm thành phần, con trỏ this
Con trỏ this là con trỏ tới chính đối tượng của nó
Con trỏ this là đối thứ nhất của hàm thành phần
Các thuộc tính viết trong hàm inputdata() gọi bởi một đối
tượng được hiểu là thuộc chính đối tượng đó do con trỏ this trỏ
tới
Cách viết tường minh lại hàm inputdata()
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
void point::inputdata(){
cout <<"\n Nhap hoanh do va tung do cua diem:”; 
cin >> this->x >>this-> y ; 
cout << “\n Nhap ma mau cua diem: “; 
cin >> this->m ;
}
5/12/2015
38
Đối của hàm thành phần, con trỏ this
Tham số truyền cho đối con trỏ this chính là địa chỉ của đối
tượng đi kèm với phương thức trong lời gọi phương thức
Ví dụ:
point a;
a.inputdata()
Trong trường hợp này tham số truyền cho con trỏ this chính
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
là địa chỉ của a:
this = &a
Con trỏ this còn được dùng trong các hàm thành phần cần trả 
lại chính đối tượng có phương thức đang triển khai.
5/12/2015
39
Đối tượng hằng và các hàm thành phần hằng
Đối tượng hằng là đối tượng được khai báo với từ khoá cons
Mọi ý định sửa đổi các đối tượng hằng đều bị chương trình 
báo lỗi khi biên dịch
Các hàm thành phần "không sủa đổi dữ liệu của lớp", tức là 
các hàm thành phần hằng và là các hàm được khai báo với từ
khoá const, mới được phép thực hiện trên các đối tượng hằng
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Khi viết các hàm thành phần của lớp, cần xác định ngay hàm 
nào cần sửa hàm nào không cần sửa đổi dữ liệu của lớp và đặt 
thêm từ khoá const tương ứng trong khai báo và định nghĩa
hàm.
5/12/2015
40
Đối tượng hằng và các hàm thành phần hằng
Ví dụ:
class Matrix{
int row,col;
double data[100][100];
public:
void Transpose(); 
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
double Det() const; // hàm thành phần hằng
};
int main(){
Matrix const m; m.Transpose(); // error
// OK vì Det() là hàm thành phần hằng
double d = m.Det(); }
5/12/2015
41
Định nghĩa lớp- Hàm dựng (tạo)/ Cấu tử
Các đối tượng cần được khởi tạo dữ liệu thành phần hoặc
gán bộ nhớ động trong quá trình sinh ra để tránh việc trả lại các
giá trị không mong muốn trong quá trình thao tác chúng
Hàm dựng cũng là một hàm thành phần của lớp (nhưng là
hàm đặc biệt) được tự động gọi bất cứ khi nào một đối tượng
mới của lớp này được tạo ra
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Chương trình dịch sẽ cấp phát bộ nhớ cho đối tượng sau đó
sẽ gọi đến hàm dựng
Hàm dựng sẽ khởi gán giá trị cho các thuộc tính của đối
tượng và có thể thực hiện một số công việc khác nhằm chuẩn
bị cho đối tượng mới.
5/12/2015
42
Định nghĩa lớp- Hàm dựng (tạo)/ Cấu tử
Hàm dựng phải có tên giống tên lớp, không có giá trị trả về
(kể cả void).
Nếu không định nghĩa hàm dựng của một lớp, trình biên dịch
sẽ sinh ra hàm dựng ngầm định.
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
 Hàm dựng ngầm định không có đối và chỉ đơn thuần đặt
không vào mọi byte của biến thể nghiệm của một đối tượng
Một lớp có thể có nhiều hơn một hàm dựng (cùng tên, khác
bộ đối số)
5/12/2015
43
Định nghĩa lớp- Hàm dựng (tạo)/ Cấu tử
class point
{
private:
int x,y,m;
public:
point()// hàm dựng không ñối
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
{x=0; y=0; m=1;}
//hàm dựng có ñối
point(int x1, int y1, int m1);
};
5/12/2015
44
Định nghĩa lớp- Hàm dựng (tạo)/ Cấu tử
point :: point(int x1, int y1, int m1) 
{x = x1; y = y1; m = m1; }
Ví dụ:
point a; // Gọi tới hàm dựng không ñối.
// Kết quả a.x = 0, a.y = 0, a.m = 1
point b(300, 100, 5);// Gọi tới hàm dựng có ñối.
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
// Kết quả b.x = 300, b.y = 100, b.m = 5
point c[5] ;// Gọi tới hàm dựng không ñối 5 lần
 Các hàm có đối kiểu lớp, thì đối chỉ xem là các tham số hình
thức, vì vậy khai báo đối (trong dòng đầu của hàm) sẽ không
tạo ra đối tượng mới và do đó không gọi tới các hàm dựng
5/12/2015
45
Định nghĩa lớp- Hàm dựng sao chép
Một hàm dựng tạo ra đối tượng mới từ đối tượng đã có được
gọi là hàm dựng sao chép.
Hàm dựng sao chép chỉ có một đối: tham khảo tới một đối
tượng thuộc cùng lớp
Ví dụ:
point::point(const point& source)
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
{
x= source.x;
y= source.y;
m= source.m;
}
5/12/2015
46
Định nghĩa lớp- Hàm dựng sao chép
Nếu không được định nghĩa, trình biên dịch sẽ tạo ra cấu tử
sao chép ngầm định. Cấu tử này sao đối tượng nguồn theo từng
bit sang đối tượng mới.
Hàm dựng sao chép trong ví dụ trên không khác gì hàm dựng
sao chép mặc định.
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
 Khi lớp có các thuộc tính con trỏ hoặc tham chiếu, thì hàm
dựng sao chép mặc định chưa đáp ứng được yêu cầu (ví dụ sao
chép mặc định hai con trỏ của 2 đối tượng thì hai đối tượng
dùng chung bộ nhớ con trỏ-> hai đối tượng không độc lập). 
5/12/2015
47
Định nghĩa lớp- Toán tử gán =
Nếu không định nghĩa toán tử này, trình biên dịch sẽ sinh ra
toán tử gán mặc định.
Toán tử mặc định này sẽ sao chép từng bit từ nơi nguồn sang 
nơi nhận.
Hàm dựng sao chép tạo ra đối tượng mới trong khi toán tử
gán chỉ thay đổi giá trị của đối tượng hiện có.
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
point& point::operator=(const point& source){
if (this != &source)
{
x= source.x; y = source.y; m=source.m;
}
}
5/12/2015
48
Định nghĩa lớp- Hàm hủy/ Hủy tử
Hàm hủy thực hiện chức năng ngược lại với hàm dựng
Tự động gọi khi đối tượng bị hủy, hoặc do kết thúc phạm vi tồn
tại của nó hoặc do được cấp phát động và được giải phóng bằng
delete
Hủy tử phải có tên giống tên lớp, nhưng có thêm dấu ~ phía
trước, không có đối số và không có kiểu trả về (kể cả void).
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
point ::~ point()
{
}
Nếu không định nghĩa hàm hủy, thì một hàm hủy mặc định
không làm gì cả được phát sinh. Đối với nhiều lớp thì hàm hủy
mặc định là đủ, và không cần đưa vào một hàm hủy mới
5/12/2015
49
Các lớp được định nghĩa với struct và union
Các lớp có thể định nghĩa bằng các từ khóa struct và union.
Chỉ có một sự khác nhau là các thành phần của lớp được khai
báo với struct và union có quyền truy cập mặc định là public.
Với union, nó chỉ chứa một thành phần dữ liệu tại một thời
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
điểm.
5/12/2015
50
Quá tải/ Nạp chồng/ Định nghĩa lại các toán tử
Cú pháp:
type operator sign (parameters) { /*...*/ }
Ví dụ:
point operator=(point a);
point operator + (point a);
point operator - (point a);
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
5/12/2015
51
Quá tải/ Nạp chồng/ Định nghĩa lại các toán tử
Khi nạp chồng toán tử cần chú ý xem toán tử là một ngôi
(unary) hay hai ngôi (binary).
Toán tử một ngôi thì danh sách rỗng
Toán tử hai ngôi thì danh sách có một tham số
Toán tử () có thể có số tham số tuỳ ý
Những toán tử sau không thể nạp chồng
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
5/12/2015
52
Một số điểm lưu ý về lớp
Hàm dựng và hàm hủy đặc biệt quan trọng với những 
lớp có thành phần dữ liệu con trỏ sử dụng cấp phát bộ 
nhớ động và mảng bởi đây là các thành phần không 
được khởi tạo, sao chép hay giải toả tự động đúng.
 Để chúng có thể hoạt động được, tối thiểu phải triển 
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
khai:
Hàm dựng mặc định
 Hàm dựng sao chép
Hàm hủy
Ngoài ra để dễ sử dụng, nên triển khai toán tử gán 
(operator = ()).
5/12/2015
53
Ví dụ về lớp véc tơ
class Vector
{
private:
double * m_pData;
int m_nSize;
public:
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Vector();
Vector(int n);
Vector(const double& val, int n);
Vector& operator=(const Vector& va);
~Vector();
5/12/2015
54
Ví dụ về lớp véc tơ
double& operator[](int n);
Vector operator+(const Vector& x);
Vector operator-(const double& x);
};
Vector::Vector()
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
{
m_nSize = 0;
m_pData = 0; // Giong nhu m_pData = NULL;
}
5/12/2015
55
Ví dụ về lớp véc tơ
Vector::Vector(int n){
m_nSize = n;
m_pData = new double[m_nSize];
for (int i = 0; i < m_nSize; i++)
m_pData[i] = 0.0;
}
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Vector::Vector(const double& val, int n){
m_nSize = n;
m_pData = new double[m_nSize];
for (int i = 0; i < m_nSize; i++)
m_pData[i] = val;
}
5/12/2015
56
Ví dụ về lớp véc tơ
Vector::~Vector(){
delete [] m_pData; // Chú ý dẫu []
}
Vector& Vector::operator=(const Vector& va)
{
delete [] m_pData;
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
this->m_nSize = va.m_nSize;
this->m_pData = new double [m_nSize];
for (int i = 0; i < m_nSize; i++)
this->m_pData[i] = va.m_pData[i];
return *this;
}
5/12/2015
57
Ví dụ về lớp véc tơ
double& Vector::operator[](int i)
{
return m_pData[i];
}
Vector Vector::operator+(const Vector& x)
{
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
Vector t(this->m_nSize);
for (int i = 0; i < m_nSize; i++)
t.m_pData[i] = this->m_pData[i]+x.m_pData[i];
return t;
}
5/12/2015
58
Ví dụ về lớp véc tơ
Vector Vector::operator-(const double& x){
Vector t(this->m_nSize);
for (int i = 0; i < m_nSize; i++)
t.m_pData[i] = this->m_pData[i]-x;
return t;
}
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
int main(){
Vector v; // Constructor mặc ñịnh ñược gọi
// Constructor với 2 tham số ñược gọi
Vector u(1.0, 2); 
Vector x(u); // Constructor sao chép (copy)
v=x+u;// toán tử cộng và gán ñược gọi }
5/12/2015
59
Thành phần tĩnh (static)
Một lớp có thể chứa các thành phần tĩnh, hoặc dữ liệu hoặc
hàm
Thành phần dữ liệu tĩnh: chỉ có một giá trị duy nhất cho mọi đối
tượng của lớp đó và tồn tại ngay cả khi không có đối tượng nào
của lớp đó.
Hàm thành phần tĩnh: dùng để truy xuất các biến tĩnh được
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
xác định là private
Hàm thành phần tĩnh không gắn với một đối tượng nào cụ thể
của lớp, có thể gọi trực tiếp bằng tên lớp với toán tử ::
5/12/2015
60
Thành phần tĩnh (static)
#include 
using namespace std;
class CDummy {
private:
static int m;
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
public:
static int n;
CDummy () { n++; m++ };
~CDummy () { n--; m--};
static int getnumcount(){return m;}
};
5/12/2015
61
Thành phần tĩnh (static)
int CDummy::n=0;
int CDummy::m=0;
int main () {
CDummy a;
CDummy b[5];
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
CDummy * c = new CDummy;
cout << a.n << endl; 
//Gọi a.m là sai, gọi Cdummy::getnumcount();
delete c;
cout << CDummy::n << endl;
return 0;}
5/12/2015
62
Hàm bạn hữu (friend)
Ngoài quy tắc trao quyền truy cập thông qua các từ khoá truy
cập, C++ còn cho phép trao quyền truy cập các thành phần của
một lớp cho một số hàm hay lớp khác, tạo thuận lợi cho việc
triển khai và sử dụng chúng.
Các hàm bạn là các hàm không phải là thành phần của lớp, 
được khai báo với từ khoá friend và có quyền truy cập đến cả 
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
các thành phần private và protected của lớp.
Một lớp bạn B của lớp A là lớp có tên được liệt kê trong phần 
khai báo của lớp A với từ khoá friend và các hàm thành phần 
của B có quyền truy cập đến các thành phần private và
protected của lớp A.
5/12/2015
63
Hàm bạn hữu (friend)
class Matrix{
public:
Matrix AddTo(Matrix const & m);
friend Matrix Add(Matrix const & m1, Matrix const & 
m2);
friend Matrix operator + (Matrix const & m1, Matrix
TRƯỜNG ĐẠI HỌC 
BÁCH KHOA HÀ NỘI
const & m2);
};
Matrix m1, m2, m3, m4;
m3 = m1.AddTo(m2); // gọi hàm thành phần Addto()
m4 = Add(m1, m2); // Gọi hàm bạn hữu Add()
m4 = m1 + m2; // Gọi hàm bạn hữu là toán tử cộng

File đính kèm:

  • pdfbai_giang_ngon_ngu_lap_trinh_c_va_c_bai_6_cau_truc_va_lop_do.pdf