Tổ chức thành các chương trình con(hay các
module)
ã Mỗi chương trình con đảm nhận xử lý một công việc
nhỏ hay một nhóm công việc trong toàn bộ hệ thống
ã Mỗi chương trình con này lại có thể chia nhỏ thành
các chương trình con nhỏ hơn
Chương trình = Cấu trúc dữ liệu + Giải thuật
ã sử dụng các lệnh có cấu trúc: for, do, while, if
then else .
ã các ngôn ngữ: Pascal, C, .
ã chương trình là tập các hàm/thủ tục
ã Ưu điểm
– chương trình được module hóa, do đó dễ hiểu,
dễ bảo trì hơn
– dễ dàng tạo ra các thư viện phần mềm
11
31 trang |
Chia sẻ: tlsuongmuoi | Lượt xem: 2276 | Lượt tải: 0
Bạn đang xem trước 20 trang tài liệu Cơ bản về hướng đối tượng và C++, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
1• Bài giảng LTHĐT, Trần Minh Châu, Đại học
Công nghệ ĐH Quốc gia HN ,
• Bài giảng LTHĐT, Nguyễn Việt Hà, Đại học
Công nghệ ĐH Quốc gia HN ,
• Bài giảng LTHĐT, Nguyễn Ngọc Long, ĐH
KHTN TPHCM
• Bài giảng LTHĐT, Huỳnh Lê Tấn Tài, ĐH KHTN
TPHCM
• C++ How to Program, Dietel
• ……………………….
2
• Tạo ra sản phẩm tốt một cách có hiệu quả
• Nắm bắt được công nghệ
3
• Một số hệ Unix chứa khoảng 4M dòng lệnh
• MS Windows chứa hàng chục triệu dòng lệnh
• Người dùng ngày càng đòi hỏi nhiều chức
năng, đặc biệt là chức năng thông minh
• Phần mềm luôn cần được sửa đổi
4
• Cần kiểm soát chi phí
– Chi phí phát triển
Chi phí bảo trì–
• Giải pháp chính là sử dụng lại(tái sử dụng)
– Giảm chi phí và thời gian phát triển
ấ– Nâng cao ch t lượng
5
• Cần dễ hiểu
• Được coi là chính xác
• Có giao diện rõ ràng
• Tính module hóa
• Không yêu cầu thay đổi khi sử dụng trong
chương trình mới
6
• Lập trình không có cấu trúc
• Lập trình có cấu trúc (lập trình thủ tục),hướng
chức năng
• Lập trình logic, lập trình hàm
• Lập trình hướng đối tượng
7
• Là phương pháp xuất hiện đầu tiên
– các ngôn ngữ như Assembly, Basic
– sử dụng các biến toàn cục
– lạm dụng lệnh GOTO
• Các nhược điểm
– khó hiểu, khó bảo trì, hầu như không thể sử dụng lại
– chất lượng kém
– chi phí cao
– không thể phát triển các ứng dụng lớn
8
Ví dụ
10 k =1
20 gosub 100
30 if y > 120 goto 60
40 k = k+1
50 goto 20
60 print k y ,
70 stop
100 3*k*k 7*k 3 y = + -
110 return
9
• Tổ chức thành các chương trình con(hay các
module)
• Mỗi chương trình con đảm nhận xử lý một công việc
nhỏ hay một nhóm công việc trong toàn bộ hệ thống
• Mỗi chương trình con này lại có thể chia nhỏ thành
các chương trình con nhỏ hơn
ấChương trình = C u trúc dữ liệu + Giải thuật
10
• sử dụng các lệnh có cấu trúc: for, do, while, if
then else ...
• các ngôn ngữ: Pascal, C, ...
ủ• chương trình là tập các hàm/th tục
• Ưu điểm
– chương trình được module hóa, do đó dễ hiểu,
dễ bảo trì hơn
– dễ dàng tạo ra các thư viện phần mềm
11
Ví dụ
struct Date {
int year, mon, day;
};
...
void print_date(Date d) {
printf(”%d / %d / %d\n”, d.day,d.mon,d.year);
}
12
• Nhược điểm
– dữ liệu và mã xử lý là tách rời
– người lập trình phải biết cấu trúc dữ liệu (vấn đề
này một thời gian dài được coi là hiển nhiên)
khi th đổi ấ t ú dữ liệ thì ã ử lý (th ật– ay c u r c u m x u
toán) phải thay đổi theo
– khó đảm bảo tính đúng đắn của dữ liệu
– không tự động khởi tạo hay giải phóng dữ liệu
động
– không mô tả được đầy đủ, trung thực hệ
thống trong thực tế
13
• Trong thế giới thực, chung quanh chúng ta là
những đối tượng đó là các thực thể có mối,
quan hệ với nhau. Ví dụ: các phòng trong một
công ty
• Lập trình hướng đối tượng (Object Oriented
Programming LTHĐT) là phương pháp lập-
trình lấy đối tượng làm nền tảng để xây dựng
thuật giải xây dựng chương trình,
14
• Đối tượng (object):
– Trong thế giới thực, khái niệm đối tượng được
hiểu như là một thực thể: người, vật hoặc một
bảng dữ liệu….
– Mỗi đối tượng sẽ tồn tại trong một hệ thống và có
ý nghĩa nhất định trong hệ thống.
– Đối tượng giúp biểu diễn tốt hơn thế giới thực
trên máy tính
15
• Lớp:
– Các đối tượng có các đặc tính tương tự nhau
được gom chung lại thành lớp đối tượng Ví dụ.
Người là một lớp đối tượng. Một lớp đối tượng
được đặc trưng bằng các thuộc tính, và các
hoạt động (hành vi, thao tác).
– Thuộc tính (attribute) là một thành phần của đối
tượng, có giá trị nhất định cho mỗi đối tượng tại
mỗi thời điểm trong hệ thống. Vd: Tên, Tuổi, Cân
à á ộ í ủ ờnặng l c c thu c t nh c a Ngư i
– Thao tác (operation) thể hiện hành vi của một
đối t tá độ l i ới á đối tượng c ng qua ạ v c c ượng
khác hoặc với chính nó. 16
ỗ ố ể• M i thao tác trên một lớp đ i tượng cụ th
tương ứng với một cài đặt cụ thể khác nhau.
Một ài đặt h ậ đ i là ột hc n ư v y ược gọ m p ương
thức (method).
ể• Cùng một thao tác(phương thức) có th được
áp dụng cho nhiều lớp đối tượng khác nhau,
ột th tá h ậ đ i là ó tí h đm ao c n ư v y ược gọ c n a
hình (polymorphism).
ố ể• Một đ i tượng cụ th thuộc một lớp được gọi là
một thể hiện (instance) của lớp đó.
ổ ể– Joe Smith, 25 tu i, nặng 58kg, là một th hiện của lớp
người. 17
• Ta dùng sơ đồ đối tượng để mô tả các lớp đối
tượng. Sơ đồ đối tượng bao gồm sơ đồ lớp và
sơ đồ thể hiện
• Sơ đồ lớp mô tả các lớp đối tượng trong hệ
thống, một lớp đối tượng được diễn tả bằng một
hình chữ nhật có 3 phần:
– phần đầu chỉ tên lớp,
– phần thứ hai mô tả các thuộc tính
– phần thứ ba mô tả các thao tác của các đối
tượng trong lớp đó.
18
Sinh vieân
Hoï teân
N ê i h
(Sinh vieân)
Nguyeãn Vaên A
1984
Teân lôùp
am s n
Maõ soá
Ñieåm TB
0610234T
9 2
Thuoäc tính
Ñi hoïc
Ñi thi
.
Thao taùc
Phaân loaïi
Sô ñoà lôùp Sô ñoà theå hieän
ốĐ i tượng = Dữ liệu + Phương thức
19
• Các lớp đối tượng - Classes
• Đóng gói – Encapsulation
ế• Thừa k - Inheritance
• Đa hình - Polymorphism
20
cách nhìn khái quát hóa về một tập các đối tượng có
chung các đặc điểm được quan tâm (và bỏ qua những
chi tiết không cần thiết). 21
• Đóng gói: Nhóm những gì có liên quan với nhau
vào làm một, để sau này có thể dùng một cái tên
để gọi đến
– Các hàm/ thủ tục đóng gói các câu lệnh
– Các đối tượng đóng gói dữ liệu của chúng và các
thủ tục có liên quan
• Che dấu thông tin: đóng gói để che một số
thông tin và chi tiết cài đặt nội bộ để bên ngoài
không nhìn thấy
– che giấu những gì mà người dùng không cần
– che giấu những gì mà mình cần giữ bí mật
22
• là cơ chế cho phép một lớp D
có được các thuộc tính và
thao tác của lớp C,
như thể các thuộc tính
và thao tác đó đã được định nghĩa tại lớp D.
• cho phép cài đặt nhiều quan hệ giữa các đối
tượng: đặc biệt hóa (“là”), khái quát hóa
23
cơ chế cho phép một tên thao tác hoặc thuộc
tính có thể được định nghĩa tại nhiều lớp và
có thể có nhiều cài đặt khác nhau tại mỗi lớp
trong các lớp đó
24
• Cung cấp được những khả năng lập trình
hướng đối tượng
– cung cấp khả năng kiểm soát truy cập
– kế thừa
– đa hình
25 26
• OOM (Object Oriented Methodology): Phương
pháp luận hướng đối tượng
• OOA (Object Oriented Analysis): Phân tích
hướng đối tượng.
• OOD: Object Oriented Design (Thiết kế hướng
đối tượng).
• OOP: Object Oriented Programming (lập trình
hướng đối tượng).
• Inheritance: Kế thừa
• Polymorphism: Đa hình
• Encapsulation: Tính đóng gói. 27
• Nguyên lý kế thừa: tránh lặp, tái sử dụng.
Ng ên lý đóng gói ha che dấ thông tin: h• uy y u c ương
trình an toàn không bị thay đổi bới những đoạn chương trình
khác
• Dễ mở rộng, nâng cấp
• Mô phỏng thế giới thực tốt hơn.
28
• Chương trình được chia thành các đối tượng.
• Các cấu trúc dữ liệu được thiết kế sao cho đặc
tả được đối tượng.
• Các hàm thao tác trên các vùng dữ liệu của đối
tượng được gắn với cấu trúc dữ liệu đó.
29
• Dữ liệu được đóng gói lại, được che giấu và không
cho phép các hàm ngoại lai truy nhập tự do.
• Các đối tượng tác động và trao đổi thông tin với
nhau qua các hàm
• Có thể dễ dàng bổ sung dữ liệu và các hàm mới vào
đối tượng nào đó khi cần thiết
• Chương trình được thiết kế theo cách tiếp cận từ
d ới lê (b )ư n ottom-up .
30
– Mở rộng của C
– Đầu thập niên 1980: Bjarne Stroustrup (Bell
Laboratories)
– Cung cấp khả năng lập trình hướng đối tượng
• Objects
• Object-oriented programs
– Ngôn ngữ lai
• C-like style
• Object-oriented style
• Both
31
• Chú thích
• Các kiểu dữ liệu
• Kiểm tra kiểu, đổi kiểu
Ph i à kh i bá• ạm v v a o
• Không gian tên
ằ• H ng
• Quản lý bộ nhớ
ế• Tham chi u
32
#include
void main() {
int n;
double d;
char s[100];
cout << “Input an int, a double and a
string ”;.
cin >> n >> d >> s;
cout << “n = “ << n << “\n”;
t “d “ d “\ ”cou << = << << n ;
cout << “s = “ << s << “\n”;
}
33
Th hi á l ø ñò hæ ø hôù ñöô á h ùt h• am c eu a a c vung n ïc cap p a c o
moät bieán.
• Kyù hieäu & ñaët tröôùc bieán hoaëc haøm ñeå xaùc ñònh
tham chieáu cuûa chuùng
• Ví duï 1:
int x = 10 *px = &x &y = x;– , ,
– *px = 20; // *px = x = y = 20
– y = 30; // y = x = *px = 30
• Ví du 2: ï
– int arrget(int *a, int i) { return a[i]; }
– arrget(a, 1) = 1; // a[1] = 1;
– cin >> arrget(a,1); // cin >> a[1];
• Ví duï 3:
– void swap1(int x, int y) { int t = x; x = y; y = t; }
– void swap2(int *x, int *y) { int *t = x; x = y; y = t; }
– void swap3(int &x, int &y) { int t = x; x = y; y = t; } 34
Choàng haøm (Functions overloading
int abs(int i);
long labs(long l);
double fabs(double d);
int abs(int i);
long abs(long l);
double abs(double d);
int abs(int i) { return abs(i);}
long abs(long l) { return labs(l);}
double abs(double d) { return fabs(d);}
void test_abs() {
int i = abs(10); // abs(int )
long l = abs(-10l); // abs(long )
double = abs(0.1l); // abs(double )
}
35
Tham soá ngaàm ñònh trong lôøi goïi haøm
void inc(int &a, int b = 1) {
a = a + b;
}
int x = 5, y = 10;
inc(x 10); // x = x + 10
Chuù yù:
,
inc(y); // y = y + 1
– Caùc tham soá coù giaù trò ngaàm ñònh phaûi ñaët cuoái danh saùch
tham soá, ñeå traùnh nhaàm laãn caùc giaù trò.
– Caùc giaù trò ngaàm ñònh cuûa tham soá chæ ñöôïc khai baùo
trong khuoân maãu haøm 36
• Toaùn töû caáp phaùt boä nhôù ñoäng new
int *x;
x = new int; // x = (int*)malloc(sizeof(int));
char *y;
y = new char[100]; // y = (char*)malloc(100);
• Toaùn töû giaûi phoùng vuøng nhôù ñoäng delete
delete x; // free(x);
delete y; // free(y);
37
• Nên khai báo hằng đối với:
Các đối tượng mà ta không định sửa đổi–
– const double PI = 3.14;
– const Date openDate(18,8,2003);
– Các tham số của hàm mà ta không định cho hàm
đó sửa đổi
id i tH i ht( t L Obj &LO)– vo pr n e g cons arge
{ cout << LO.height; }
– Các hàm thành viên không thay đổi đối tượng
chủ
– int Date::getDay() const { return day; }
38
• Một lớp bao gồm các thành phần dữ liệu hay là
thuộc tính và các phương thức hay là hàm thành
phần
• Lớp trong C++ thực chất là một kiểu dữ liệu do
người sử dụng định nghĩa
39
• Lưu giữ trạng thái: mỗi đối tượng có trạng thái
(dữ liệu của nó) và các thao tác
• Định danh: Mỗi đối tượng bất kể đang ở trạng
thái nào đều có định danh và được đối xử như
một thực thể riêng biệt.
• Thông điệp: là phương tiện để một đối tượng A
chuyển tới đối tượng B yêu cầu B thực hiện một
trong số các thao tác của B.
40
• Lớp: là khuôn mẫu để tạo các đối tượng (tạo
các thể hiện). Mỗi đối tượng có cấu trúc và hành
vi giống như lớp đối tượng mà nó được tạo từ
đó.
• Lớp là cái ta thiết kế và lập trình
Đối t là ái t t (từ ột lớ ) t i thời i• ượng c a ạo m p ạ g an
chạy.
41
class {
private:
<khai báo các thành phần riêng trong từng đối
tượng>
protected:
<khai báo các thành phần riêng trong từng đối
tượng, có thể truy cập từ lớp dẫn xuất >
public:
<khai báo các thành phần giao tiếp của từng đối
tượng>
};
<đị h hĩ ủ á hà thà h hầ h đn ng a c a c c m n p n c ưa ược
định nghĩa bên trong khai báo lớp> 42
:: (<danh
sách tham số>)
{
}
void point::display() { } ……..
43
• Tạo đối tượng:
= new
• Gọi hàm thành phần của lớp
(<d hn ư ng . n m n p n an
sách các tham số nếu có>);
Æ<tên hàm thành
phần>();
44
• Xây dựng lớp Điểm (Point) trong hình học 2D
– Thuộc tính
• Tung độ
• Hoành độ
– Thao tác (phương thức)
• Khởi tạo
• Di chuyển
• In ra màn hình
• …………..
45
/* i t */po n .cpp
#include
#include
class point {
/*khai báo các thành phần dữ liệu riêng*/
private:
int x,y;
/*khai báo các hàm thành phần công cộng*/
public:
void init(int ox, int oy);
id (i t d i t d )vo move n x, n y ;
void display();
};
46
void point::init(int ox, int oy) {
cout<<"Ham thanh phan init\n";
x = ox; y = oy;
/*x,y là các thành phần của đối tượng gọi hàm thành phần*/
}
void point::move(int dx, int dy) {
cout<<"Ham thanh phan move\n";
x += dx; y += dy;
}
void point::display() {
cout<<"Ham thanh phan display\n";
cout<<"Toa do: "<<x<<" "<<y<<"\n";
}
47
void main() {
clrscr();
point p;
p.init(2,4); /*gọi hàm thành phần từ đối tượng*/
p.display();
p.move(1,2);
p.display();
getch();
}
48
Ham thanh phan init
Ham thanh phan display
Toa do: 2 4
H th h ham an p an move
Ham thanh phan display
3 6Toa do:
49
• Trong định nghĩa của lớp ta có thể xác định khả
năng truy xuất thành phần của một lớp nào đó
từ bên ngoài phạm vi lớp
• private và public là các từ khoá xác định thuộc
tính truy xuất
• Mọi thành phần được liệt kê trong phần public
đều có thể truy xuất trong bất kỳ hàm nào
• Những thành phần được liệt kê trong phần
private chỉ được truy xuất bên trong phạm vi
lớp
50
• Trong lớp có thể có nhiều nhãn private và public
• Mỗi nhãn này có phạm vi ảnh hưởng cho đến
khi gặp một nhãn kế tiếp hoặc hết khai báo lớp
• Nhãn private đầu tiên có thể bỏ đi vì C++ ngầm
hiểu rằng các thành phần trước nhãn public đầu
tiên là private
51
class tamgiac{
i tpr va e:
float a,b,c;/*độ dài ba cạnh*/
public:
void nhap();/*nhập vào độ dài ba cạnh*/
void in();/*in ra các thông tin liên quan đến tam giác*/
private:
int loaitg();/*cho biết kiểu của tam giác: 1-d,2-vc,3-c,4-v,5-t*/
float dientich();/*tính diện tích của tam giác*/
};
52
class tamgiac{
private:
float a b c;/*độ dài ba cạnh*/ , ,
int loaitg();/*cho biết kiểu của tam giác: 1-d,2-vc,3-c,4-v,5-t*/
float dientich();/*tính diện tích của tam giác*/
public:
void nhap();/*nhập vào độ dài ba cạnh*/
void in();/*in ra các thông tin liên quan đến tam giác*/
};
53
Đối tượng như tham số của hàm thành phần
• Hàm thành phần có quyền truy nhập đến các
thành phần private của đối tượng gọi nó:
void point::init(int xx,int yy)
{
x=xx;
y=yy;
}
54
Đối tượng như tham số của hàm thành phần
• Hàm thành phần có quyền truy nhập đến tất cả các
thành phần private của các đối tượng, tham chiếu
đối tượng hay con trỏ đối tượng có cùng kiểu lớp
khi được dùng là tham số hình thức của nó
int trung(point pt) {return(x==pt.x && y==pt.y);}
int trung(point *pt) {return(x==pt->x && y==pt->y);}
int trung(point &pt) {return(x==pt.x && y==pt.y);}
55
• Từ khoá this trong định nghĩa của các hàm
thành phần lớp dùng để xác định địa chỉ của đối
tượng dùng làm tham số ngầm định cho hàm
thành phần
• Con trỏ this tham chiếu đến đối tượng đang gọi
hàm thành phần
int trung(point pt)
{return(this->x==pt.x && this->y==pt.y);}
56
point a, b; việc sao chép giá trị các thành phần
ốa.init(5,2);
b=a;
dữ liệu (x, y) từ đ i tượng a sang
đối tượng b tương ứng từng đôi một
ba
5 x5x
2 y2y
57
• Nếu hai đối tượng A và B cùng kiểu, có các
thành phần dữ liệu x,y(tĩnh) và z là một con trỏ
chỉ đến một vùng nhớ được cấp phát động
ba
2 y
5 5
2
x
y
x
zzSao chép bề mặt
vùng dữ liệu động58
• Constructor là một loại phương thức đặc biệt
dùng để khởi tạo thể hiện của lớp
• Bất kể loại cấp phát bộ nhớ nào được sử dụng
(tự động tĩnh động) mỗi khi một thể hiện của, , ,
lớp được tạo, một hàm constructor nào đó của
lớp sẽ được gọi
59
class point
{
/*khai báo các thành phần dữ liệu*/
int x;
int y;
public:
/*khai báo các thành phần hàm*/
point(int ox,int oy) {x=ox;y=oy;}/*hàm thiết lập*/
void move(int dx,int dy) ;
void display();
};
point a(5,2); //int i(5)
60
• Constructor có cùng tên với tên của lớp
• Constructor không có giá trị trả về (kể cả void)
• Constructor phải có thuộc tính public
C t t ó thể đ kh i bá hồ h• ons ruc or c ược a o c ng n ư
các hàm C++ thông thường khác
Constructor có thể được khai báo với các tham•
số có giá trị ngầm định
61
class point
{
/*khai báo các thành phần dữ liệu*/
int x;
int y;
public:
/*khai báo các thành phần hàm*/
point() {x=0;y=0};
point(int ox,int oy) {x=ox;y=oy;}/*hàm thiết lập*/
void move(int dx,int dy) ;
void display();
};
point a(5,2);
point b;
point c(3);
62
class point
{
/*khai báo các thành phần dữ liệu*/
int x;
int y;
public:
/*khai báo các thành phần hàm*/
point() {x=0;y=0};
point(int ox,int oy=1) {x=ox;y=oy;}/*hàm thiết lập*/
void move(int dx,int dy) ;
void display();
};
point a(5,2);
point b;
point c(3);
63
• Constructor mặc định (default constructor) là
constructor được gọi khi thể hiện được khai báo
ố ố ấmà không có đ i s nào được cung c p
• MyClass x;
M Cl * M Cl• y ass p = new y ass;
• Ngược lại, nếu tham số được cung cấp tại khai
báo thể hiện trình biên dịch sẽ gọi phương thức ,
constructor khác (overload)
• MyClass x(5);
• MyClass* p = new MyClass(5);
64
• Đối với constructor mặc định, nếu ta không cung
cấp một phương thức constructor nào, C++ sẽ
tự sinh constructor mặc định là một phương
thức rỗng
ế• Tuy nhiên, n u ta không định nghĩa constructor
mặc định nhưng lại có các constructor khác,
trình biên dịch sẽ báo lỗi không tìm thấy
constructor mặc định nếu ta không cung cấp
tham số khi tạo thể hiện.
65
class point
{
/*khai báo các thành phần dữ liệu*/
int x;
int y;
public:
ầ/*khai báo các thành ph n hàm*/
point(int ox,int oy=1) {x=ox;y=oy;}/*hàm thiết lập*/
void move(int dx int dy) ; ,
void display();
};
point a(5,2);
point b;
point c(3);
66
class point
{
/*khai báo các thành phần dữ liệu*/
int x;
int y;
public:
/*khai báo các thành phần hàm*/
point(int ox=0,int oy=0) {x=ox;y=oy;}/*hàm thiết lập*/
void move(int dx,int dy) ;
void display();
};
point a(5 2); ,
point b;
point c(3);
67 68
• Cũng như một phương thức constructor được gọi
khi một đối tượng được tạo, loại phương thức thứ
hai, destructor, được gọi ngay trước khi thu hồi
một đối tượng
• Destructor thường được dùng để thực hiện mọi việc
dọn dẹp cần thiết trước khi một đối tượng bị huỷ
• Destructor không có giá trị trả về, và không thể định
ốnghĩa lại (nó không bao giờ có tham s )
• Phương thức destructor trùng tên với tên lớp nhưng
có dấu ~ đặt trước
• Destructor phải có thuộc tính public
69
class vector {
i t // ố hiền n; s c u
float *v; //vùng nhớ toạ độ
public:
vector(); //Hàm thiết lập không tham số
vector(int size); //Hàm thiết lập một tham số
vector(int size, float *a);
~vector();//Hàm huỷ bỏ luôn luôn không có tham số ,
void display();
};
70
• Giả sử có lớp Vector, lớp Matrix
• Cần viết hàm nhân 1 Vector và 1 Matrix
• Hàm nhân:
Khô thể th ộ lớ V t– ng u c p ec or
– Không thể thuộc lớp Matrix
Không thể tự do–
• Giải pháp: xây dựng hàm truy cập dữ liệu.
71
• Hàm bạn không thuộc lớp, nhưng có quyền truy
cập các thành viên private.
• Khi định nghĩa một lớp, có thể khai báo rằng một
hay nhiều hàm “bạn” (bên ngoài lớp)
• Ưu điểm: kiểm soát các truy nhập ở cấp độ lớp -
không thể áp đặt hàm bạn cho một lớp nếu điều
đó không được dự trù trước trong khai báo của
lớp
72
• Hàm tự do là bạn của một lớp.
• Hàm thành phần của một lớp là bạn của một lớp
khác.
• Hàm bạn của nhiều lớp .
• Tất cả các hàm thành phần của một lớp là bạn
của một lớp khác
73
class point {
int x y; ,
public:
point(int abs =0 int ord =0) { ,
x = abs;y = ord;
}
friend int coincide (point,point);
};
74
• Vị trí của khai báo “bạn bè” trong lớp hoàn toàn
tuỳ ý
• Trong hàm bạn, không còn tham số ngầm định
this như trong hàm thành phần
• Hàm bạn của một lớp có thể có một hay nhiều
tham số, hoặc có giá trị trả về thuộc kiểu lớp đó
75 76
• Các phương thức truy vấn (query method) là các
phương thức dùng để hỏi về giá trị của các thành
viên dữ liệu của một đối tượng
• Có nhiều loại câu hỏi truy vấn có thể:
tr ấn đơn giản (“giá trị của là bao nhiê ?”)– uy v x u
– truy vấn điều kiện (“thành viên x có lớn hơn 10 không?”)
– truy vấn dẫn xuất (“tổng giá trị của các thành viên x và y
là bao nhiêu?”)
• Đặc điểm quan trọng của phương thức truy vấn là
nó không nên thay đổi trạng thái hiện tại của đối
tượng
77
• Đối với các truy vấn đơn giản, quy ước đặt tên
phươngthức: tiền tố “get” tiếp theo là tên của ,
thành viên
• int getX();
• int getSize();
• Các loại truy vấn khác nên có tên có tính mô tả
• Truy vấn điều kiện nên có tiền tố “is”
78
• Ngược lại với truy vấn, các phương thức cập
nhật thường thay đổi trạng thái của đối tượng
bằng cách sửa đổi một hoặc nhiều thành viên
dữ liệu của đối tượng đó
D đ iả hấ ủ á h hứ ậ• ạng ơn g n n t c a c c p ương t c c p
nhật là gán một giá trị nào đó cho một thành
viên dữ liệu
• Đối với dạng cập nhật đơn giản, quy ước đặt
tên: dùng tiền tố “set” kèm theo tên thành viên
ầc n sửa
• int setX(int);
79
• Nếu các phương thức get/set chỉ có nhiệm vụ cho ta
đọc và ghi giá trị cho các thành viên dữ liệu, quy
định các thành viên private để được ích lợi gì?
• Ngoài việc bảo vệ các nguyên tắc đóng gói, ta còn
cần kiểm tra xem giá trị mới cho thành viên dữ liệu
có hợp lệ hay không.
• Sử dụng phương thức truy vấn cho phép ta thực
ể ổhiện việc ki m tra trước khi thực sự thay đ i giá trị
của thành viên.
• Cho phép chỉ các dữ liệu có thể truy vấn hay thay
đổi được truy cập đến.
80
int Student::setGPA(double newGPA)
{
if ((newGPA >= 0.0) && (newGPA <= 4.0))
{
this->gpa = newGPA;
return 0; // Return 0 to indicate success
}
else
{
return -1; // Return -1 to indicate failure
}
}
81
• Đối với class, static dùng để khai báo thành
viên dữ liệu dùng chung cho mọi thể hiện của
lớp.
• một bản duy nhất tồn tại trong suốt quá trình chạy
của chương trình,
• dùng chung cho tất cả các thể hiện của lớp,
ấ ể ể• b t k lớp đó có bao nhiêu th hiện
82
• Đếm số đối tượng MyClass
83 84
85
• Từ khoá const được dùng cho các tham số của
hàm để đảm bảo các tham số được truyền cho
hà ẽ khô bị hà ử đổim s ng m s a .
• int myFunction(const int& x);
Còn tham số ẩn truyền bằng con trỏ this và•
chính là đối tượng chủ?
86
• Xeùt ñoaïn chöông trình sau:
#include
void main()
{
cout << "Hello world \n"; , .
}
Haõy söûa lai ñoan chöông trình treân ñeå coù xuaát lieäu: ï ï
Entering a C++ program saying...
Hello, world.
And then exitting…
Yeâu caàu khoâng thay ñoåi haøm main() döôùi baát kyø
hình thöùc naøo.
87
• Ñoaïn chöông trình ñöôïc söûa laïi nhö sau
#include
class Dummy
{
public:
Dummy() {cout << "Entering a C++ program saying...\n";}
~Dummy() {cout << "And then exitting...";}
};
Dummy A;
void main()
{
cout << "Hello, world.\n";
}
88
• Ñoái töông coù theå laø thaønh phaàn cuûa ñoái töông khaùc, ï ï
khi moät ñoái töôïng thuoäc lôùp “lôùn” ñöôïc taïo ra, caùc
thaønh phaàn cuûa noù cuõng ñöôïc taïo ra. Phöông thöùc
thieát laäp (neáu coù) seõ ñöôïc töï ñoäng goïi cho caùc ñoái
töôïng thaønh phaàn.
• Neáu ñoái töôïng thaønh phaàn phaûi ñöôïc cung caáp tham
soá khi thieát laäp thì ñoái töôïng keát hôïp (ñoái töôïng lôùn)
phaûi coù phöông thöùc thieát laäp ñeå cung caáp tham soá
thieát laäp cho caùc ñoái töôïng thaønh phaàn.
89
• Cuù phaùp ñeå khôûi ñoäng ñoái töông thaønh phaàn laø duøng ï
daáu hai chaám (:) theo sau bôûi teân thaønh phaàn vaø
tham soá khôûi ñoäng.
• Khi ñoái töôïng keát hôïp bò huyû ñi thì caùc ñoái töôïng
thaønh phaàn cuûa noù cuõng bò huyû ñi, nghóa laø phöông
thöùc huyû boû seõ ñöôïc goïi cho caùc ñoái töôïng thaønh
phaàn, sau khi phöông thöùc huyû boû cuûa ñoái töôïng keát
hôïp ñöôïc goïi.
90
class Diem
{
double x,y;
public:
Diem(double xx, double yy) {x = xx; y = yy;}
// ...
};
class TamGiac
{
Diem A,B,C;
public:
void Ve() const;
// ...
};
TamGiac t; // Bao sai
Diem D;
91
class String
{
char *p;
public:
String(char *s) {p = strdup(s);}
String(const String &s) {p = strdup(s.p);}
~String() {cout << "delete "<< (void *)p << "\n";
delete [] p;
//...
};
class SinhVien
{
String MaSo;
String HoTen;
int NamSinh;
public:
};
SinhVien s; // Bao sai 92
class Diem
{
double x,y;
public:
Diem(double xx, double yy {x = xx; y = yy;}
// ...
};
93
class TamGiac
{
Diem A,B,C;
public:
TamGiac(double xA, double yA, double xB, double
yB, double xC, double yC):A(xA,yA),
B(xB,yB),C(xC,yC){}
void Ve() const;
// ...
};
TamGiac t(100,100,200,400,300,300); 94
class String
{
char *p;
public:
String(char *s) {p = strdup(s);}
String(const String &s) {p = strdup(s.p);}
~String() {cout << "delete "<< (void *)p << "\n";
delete [] p;
//...
};
95
class SinhVien
{
String MaSo;
String HoTen;
int NamSinh;
public:
SinhVien(char *ht, char *ms, int ns):HoTen(ht),
MaSo(ms){NamSinh = ns;}
//...
};
SinhVien s(“Nguyen Van Beo”, “19920005”, 1985); //Ok
96
Khôûi ñoäng ñoái töôïng thaønh phaàn: Duøng
daáu hai chaám (:)
• Cuù phaùp duøng daáu hai chaám cuõng ñöôïc duøng cho
ñoái töôïng thaønh phaàn thuoäc kieåu cô baûn.
class Diem {
double x,y;
public:
Diem(double xx, double yy):x(xx), y(yy){}
// ...
};
class SinhVien {
String MaSo, HoTen;
int NamSinh;
public:
SinhVien(char *ht, char *ms, int ns):HoTen(ht),
MaSo(ms) NamSinh(ns){},
//...
}; 97
• Khi ñoái töôïng keát hôïp bò huyû boû, caùc ñoái töôïng
thaønh phaàn cuûa noù cuõng bò huyû boû.
class SinhVien
{
String MaSo HoTen; ,
int NamSinh;
int SoMon;
double *Diem;
public:
SinhVien(char *ht, char *ms, int ns, int sm, double
*d);
~SinhVien() {delete [] Diem;}
//...
};
SinhVien::SinhVien(char *ht, char *ms, int ns, int sm,
double *d):HoTen(ht), MaSo(ms), NamSinh(ns),
SoMon(sm)
{
memcpy(Diem = new double[SoMon], d,
SoMon*sizeof(double));
}
98
• Khi moät maûng ñöôïc taïo ra, caùc phaàn töû cuûa noù cuõng ñöôïc taïo
ra, do ñoù phöông thöùc thieát laäp seõ ñöôïc goïi cho töøng phaàn töû
moät.
• Vì khoâng theå cung caáp tham soá khôûi ñoäng cho taát caû caùc
phaàn töû cuûa maûng neân khi khai baùo maûng, moãi ñoái töôïng
trong maûng phaûi coù khaû naêng töï khôûi ñoäng, nghóa laø coù theå
ñöôïc thieát laäp khoâng caàn tham soá.
• Ñoái töông coù khaû naêng tö khôûi ñoäng trong caùc tröôøng hôp ï ï ï
sau:
– Lôùp khoâng coù phöông thöùc thieát laäp.
– Lôùp coù phöông thöùc thieát laäp khoâng tham soá.
– Lôùp coù phöông thöùc thieát laäp maø moïi tham soá ñeàu coù giaù trò maëc
nhieân.
99
class Diem {
double x,y;
public:
Diem(double xx, double yy):x(xx), y(yy) {}
void Set(double xx, double yy) {x = xx, y = yy;}
// ...
};
class String {
char *p;
ipubl c:
String(char *s) {p = strdup(s);}
String(const String &s) {p = strdup(s.p);}
String() {~
cout << "delete "<< (void *)p << "\n";
delete [] p;
}
// ...
100
class SinhVien
{
String MaSo;
String HoTen;
int NamSinh;
public:
SinhVien(char *ht, char *ms, int
ns):HoTen(ht), MaSo(ms),
i h( ){}NamS n ns
//...
};
String as[3]; // Bao sai
Diem ad[5]; // Bao sai
SinhVien asv[7]; // Bao sai
101
class Diem
{
double x,y;
public:
i (d bl d bl ) ( ) ( ){}D em ou e xx = 0, ou e yy = 0 :x xx , y yy
void Set(double xx, double yy) {x = xx, y = yy;}
// ...
};
class String
{
char *p;
public:
String(char *s = “”) {p = strdup(s);}
String(const String &s) {p = strdup(s.p);}
~String() {cout << "delete "<< (void *)p << "\n";
delete [] p;}
// ...
102
class SinhVien
{
String MaSo;
String HoTen;
i i hnt NamS n ;
public:
SinhVien(char *ht = “Nguyen Van A”, char *ms =
“19920014” int ns 1982):HoTen(ht), = ,
MaSo(ms), NamSinh(ns){}
//...
};
String as[3]; // Ok: Ca ba phan tu deu la chuoi rong
Diem ad[5]; // Ok: ca 5 diem deu la (0,0)
SinhVien asv[7]; // Ok: Het sai ca 7 sinh vien deu
co cung hoten, maso, namsinh 103
class Diem
{
double x,y;
public:
i (d bl d bl ) ( ) ( ){}D em ou e xx, ou e yy :x xx , y yy
Diem():x(0), y(0){}
// ...
};
class String
{
char *p;
public:
String(char *s) {p = strdup(s);}
String() {p = strdup(“”);}
~String() {cout << "delete "<< (void *)p << "\n";
delete [] p;}
// ...
104
class SinhVien {
String MaSo;
String HoTen;
int NamSinh;
public:
SinhVien(char *ht, char *ms, int ns):HoTen(ht),
MaSo(ms), NamSinh(ns){}
SinhVien():HoTen(“Nguyen Van A”), MaSo(“19920014”),
NamSinh(1982){}
//...
};
String as[3]; // Ca ba phan tu deu la chuoi rong
Diem ad[5]; // ca 5 diem deu la (0,0)
i h i [ ] // i h i d hS n V en asv 7 ; Ca 7 s n v en eu co cung oten,
maso, namsinh
105
• Ñoái töông ñöôc caáp phaùt ñoäng laø caùc ñoái töông ñöôc ï ï ï ï
taïo ra baèng pheùp toaùn new vaø bò huyû ñi baèng pheùp
toaùn delete
• Pheùp toaùn new caáp ñoái töôïng trong vuøng heap (hay
vuøng free store) vaø goi phöông thöùc thieát laäp cho ï
ñoái töôïng ñöôïc caáp.
• Duøng new coù theå caáp moät ñoái töông vaø duøng delete ï
ñeå huyû moät ñoái töôïng.
• Duøng new vaø delete cuõng coù theå caáp nhieàu ñoái
töôïng vaø huyû nhieàu ñoái töôïng. 106
class String {
char *p;
public:
String(char *s) {p = strdup(s);}
String(const String &s) {p = strdup(s.p);}
~String() {delete [] p;}
//...
};
class Diem {
double x,y;
public:
Diem(double xx, double yy):x(xx),y(yy){};
//...
};
//... 107
int *pi = new int;
int *pj = new int(15);
Diem *pd = new Diem(20,40);
String *pa = new String("Nguyen Van A");
//...
delete pa;
delete pd;
delete pj;
delete pi;
108
• Trong tröôøng hôïp caáp nhieàu ñoái töôïng, ta khoâng theå
cung caáp tham soá cho töøng phaàn töû ñöôc caáp: ï
int *pai = new int[10];
Diem *pad = new Diem[5]; // Bao sai
String *pas = new String[5]; // Bao sai
• Thoâng baùo loãi cho ñoaïn chöông trình treân nhö sau:
Cannot find default constructor to initialize array element of
type 'Diem'
Cannot find default constructor to initialize array element of
type String’
• Loãi treân ñöôïc khaéc phuïc baèng caùch cung caáp
phöông thöùc thieát laäp ñeå ñoái töông coù khaû naêng töï ï
khôûi ñoäng.
109
class String
{
char *p;
public:
String(char *s = "Alibaba") {p = strdup(s);}
String(const String &s) {p = strdup(s.p);}
~String() {delete [] p;}
//...
};
class Diem
{
double x,y;
public:
Diem(double xx, double yy):x(xx),y(yy){};
Diem():x(0),y(0){};
//...
};
110
• Khi ñoù moïi phaàn töû ñöôïc caáp ñeàu ñöôïc khôûi ñoäng vôùi cuøng
giaù trò
i i i [ ]nt *pa = new nt 10 ;
Diem *pad = new Diem[5];
// ca 5 diem co cung toa do (0,0)
String *pas new String[5] = ;
// Ca 5 chuoi cung duoc khoi dong bang “Alibaba”
• Vieäc huyû nhieàu ñoái töôïng ñöôïc thöïc hieän baèng caùch duøng
delete vaø coù theâm daáu [] ôû tröôùc .
– delete [] pas;
– delete [] pad;
d l t [] i– e e e pa ;
• (?) Coù theå thay ba phaùt bieåu treân baèng moät phaùt bieåu duy
nhaát sau ñöôïc khoâng ?
delete pas,pad,pai; // ??
111
• Lôùp coù hai phaàn taùch rôøi, moät laø phaàn giao dieän khai baùo
trong phaàn public ñeå ngöôøi söû duïng “thaáy” vaø söû duïng, vaø
hai laø chi tieát caøi ñaët bao goàm döõ lieäu khai baùo trong phaàn
private cuûa lôùp vaø chi tieát maõ hoaù caùc haøm thaønh phaàn, voâ
hình ñoái vôùi ngöôøi duøng.
• Ta coù theå thay ñoåi uyeån chuyeån chi tieát caøi ñaët, nghóa laø coù
theå thay ñoåi toå chöùc döõ lieäu cuûa lôùp, cuõng nhö coù theå thay
ñoåi chi tieát thöc hieän caùc haøm thaønh phaàn (do sö thay ñoåi toå ï ï
chöùc döõ lieäu hoaëc ñeå caûi tieán giaûi thuaät). Nhöng neáu baûo
ñaûm khoâng thay ñoåi phaàn giao dieän thì khoâng aûnh höôûng ñeán
øi û d ø d ñ ù kh â l ø ñ å õ ki á t ù û h ängöô sö uïng, va o o ong am o vô en ruc cua e
thoáng.
• Lôùp ThoiDiem coù theå ñöôc caøi ñaët vôùi caùc thaønh phaàn döõ ï
lieäu laø giôø, phuùt, giaây hoaëc toång soá giaây tính töø 0 giôø.
112
class ThoiDiem
{
int gio, phut, giay;
static bool HopLe(int g, int p, int gy);
public:
ThoiDiem(int g = 0, int p = 0, int gy = 0) {Set(g,p,gy);}
void Set(int g, int p, int gy);
int LayGio() const {return gio;}
int LayPhut() const {return phut;}
int LayGiay() const {return giay;}
void Nhap();
void Xuat() const;
void Tang();
void Giam();
}; 113
class ThoiDiem
{
long tsgiay;
static bool HopLe(int g, int p, int gy);
public:
ThoiDiem(int g = 0, int p = 0, int gy = 0) {Set(g,p,gy);}
void Set(int g, int p, int gy);
int LayGio() const {return tsgiay / 3600;}
int LayPhut() const {return (tsgiay%3600)/60;}
int LayGiay() const {return tsgiay % 60;}
void Nhap();
void Xuat() const;
void Tang();
void Giam();
}; 114
• Khi ta coù theå nghó ñeán “noù” nhö moät khaùi nieäm rieâng reõ, xaây
döïng lôùp bieåu dieãn khaùi nieäm ñoù. Ví duï lôùp SinhVien.
• Khi ta nghó ñeán “noù” nhö moät thöïc theå rieâng reõ, taïo ñoái
töôïng thuoäc lôùp. Ví duï ñoái töôïng Sinh vieân “Nguyen Van A”
(vaø caùc thuoäc tính khaùc nhö maõ soá naêm sinh ) , … .
• Lôùp laø bieåu dieãn cuï theå cuûa moät khaùi nieäm, vì vaäy lôùp luoân
luoân laø DANH TÖØ.
• Caùc thuoäc tính cuûa lôùp laø caùc thaønh phaàn döõ lieäu, neân chuùng
luoân luoân laø DANH TÖØ.
C ù h ø h ø h h à l ø ù h ù hæ õ h ñ ä û l ù• ac am t an p an a cac t ao tac c ro oaït ong cua ôp
neân caùc haøm naøy laø ÑOÄNG TÖØ.
• Caùc thuoäc tính döõ lieäu phaûi vöøa ñuû ñeå moâ taû khaùi nieäm,
khoâng dö, khoâng thieáu.
115
Caùc thuoäc tính coù theå ñöôïc suy dieãn töø nhöõng thuoäc tính khaùc
thì duøng haøm thaønh phaàn ñeå thöïc hieän tính toaùn. Chu vi, dieän
tích tam giaùc laø thuoäc tính suy dieãn
// SAI // DUNG
.
class TamGiac
{
Diem A,B,C;
class TamGiac
{
double ChuVi,
DienTich;
public:
Diem A,B,C;
bli//...
};
pu c:
//...
double ChuVi()const;
double DienTich() const;
}
116
• Caù bieät coù theå coù moät soá thuoäc tính suy dieãn ñoøi hoûi
nhieàu taøi nguyeân hoaëc thôøi gian ñeå thöïc hieän tính
toaùn, ta coù theå khai baùo laø döõ lieäu thaønh phaàn. Ví duï
tuoåi trung bình cuûa daân Vieät Nam.
class QuocGia
{
long DanSo;
double DienTich;
double TuoiTrungBinh;
//...
public:
double TinhTuoiTB() const;
//...
}; 117
• Chi tieát caøi ñaët, bao goàm döõ lieäu vaø phaàn maõ hoaù caùc haøm
thaønh phaàn coù theå thay ñoåi uyeån chuyeån nhöng phaàn giao
dieän, nghóa laø phaàn khai baùo caùc haøm thaønh phaàn caàn phaûi
coá ñònh ñeå khoâng aûnh höôûng ñeán ngöôøi söû dung Tuy nhieân ï
neân coá gaéng caøi ñaët döõ lieäu moät caùch töï nhieân theo ñuùng
khaùi nieäm.// NEN // KHONG NEN
class PhanSo
{
int tu mau;
class PhanSo
{
long tu_mau;
,
public:
//...
};
public:
//...
};
118
D õ li ä h ø h h à â ñ k á h h ì h â• ö eu t an p an nen öôïc et ôïp t ay v p an
raõ
// NEN // KHONG NEN
class TamGiac
{
Diem A,B,C;
class TamGiac
{
double xA, yA, xB, yB,
public:
//...
};
xC, yC;
public:
//...
class HinhTron
{
Diem Tam;
};
class HinhTron
{
double BanKinh;
public:
//...
double tx, ty,
BanKinh;
public:
//
};
...
}; 119
• Chi tieát caøi ñaët, bao goàm döõ lieäu vaø phaàn maõ hoaù caùc haøm
thaønh phaàn coù theå thay ñoåi uyeån chuyeån nhöng phaàn giao
dieän, nghóa laø phaàn khai baùo caùc haøm thaønh phaàn caàn phaûi
coá ñònh ñeå khoâng aûnh höôûng ñeán ngöôøi söû duïng (xem phaàn
2 4). .
• Döõ lieäu thaønh phaàn neân ñöôïc keát hôïp thay vì phaân raõ// NEN
class TamGiac
// KHONG NEN
class TamGiac
{
Diem A,B,C;
public:
{
double xA, yA, xB, yB,
xC, yC;
//...
};
public:
//...
};
120
• Trong moïi tröôøng hôïp, neân coù phöông thöùc thieát laäp
ñeå khôûi ñoäng ñoái töôïng.
• Neân coù phöông thöùc thieát laäp coù khaû naêng töï khôûi
ñoäng khoâng caàn tham soá.
• Neáu ñoái töôïng coù nhu caàu caáp phaùt taøi nguyeân thì
phaûi coù phöông thöùc thieát laäp, phöông thöùc thieát laäp
åsao cheùp ñe khôûi ñoäng ñoái töôïng baèng ñoái töôïng
cuøng kieåu vaø coù phöông thöùc huyû boû ñeå doïn deïp.
øi ø h ûi ù h ù ù ( h i á h )Ngoa ra con p a co p ep gan c öông t ep t eo .
• Ngöôïc laïi, ñoái töôïng ñôn giaûn khoâng caàn taøi nguyeân
à árieâng thì khoâng can phöông thöùc thiet laäp sao cheùp
vaø cuõng khoâng caàn phöông thöùc huyû boû. 121
Các file đính kèm theo tài liệu này:
- Cơ bản về hướng đối tượng và C++.pdf