Kỹ thuật lập trình - Chương 7: Quan hệ lớp

7.1 Quanhệlớp

7.2 Dẫnxuấtvàthừakế

7.3 Hàmảovànguyênlý₫ahình/₫axạ

7.4 Vídụthưviệnkhốichứcnăng

pdf33 trang | Chuyên mục: C/C++ | Chia sẻ: dkS00TYs | Lượt xem: 1527 | Lượt tải: 1download
Tóm tắt nội dung Kỹ thuật lập trình - Chương 7: Quan hệ lớp, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
viên
ƒ Các hàm thành viên của lớp dẫn xuất có thể truy nhập thành
viên "protected" ₫ịnh nghĩa ở lớp cơ sở, nhưng cũng không thể
truy nhập các thành viên "private" ₫ịnh nghĩa ở lớp cơ sở
Phản ví dụ:
Rectangle rect(0,0,50,100);
Square square(0,0,50);
square.TL = 10;
ƒ Lớp dẫn xuất ₫ược "thừa kế" cấu trúc dữ liệu và các phép toán
₫ã ₫ược ₫ịnh nghĩa trong lớp cơ sở, nhưng không nhất thiết có
quyền sử dụng trực tiếp, mà phải qua các phép toán (các hàm
công cộng hoặc hàm public)
ƒ Quyền truy nhập của các thành viên "public" và "protected" ở
lớp dẫn xuất ₫ược giữ nguyên trong lớp cơ sở
15
©
2
0
0
4
,
H
O
À
N
G
M
I
N
H
S
Ơ
N
Chương 7: Quan hệ lớp © 2007 AC - HUT
Thuộc tính truy nhập kế thừa
Thuộc tính kế thừa của lớp dẫn xuất Y
Thuộc tính truy nhập của 
các thành viên lớp cơ sở X class Y: private X class Y: public X
private Được kế thừa nhưng các thành viên của X 
không thể truy nhập trong Y
protected
Các thành viên của X 
sẽ trở thành các 
thành viên private
của Y và có thể ₫ược 
truy nhập trong Y
Các thành viên của X 
sẽ trở thành các thành 
viên protected của Y 
và có thể truy nhập 
trong Y
public
Thành viên của X sẽ
trở thành thành viên 
private của Y và có
thể truy nhập trong Y
Thành viên của X sẽ
trở thành thành viên 
public của Y và có thể
truy nhập trong Y
16
©
2
0
0
4
,
H
O
À
N
G
M
I
N
H
S
Ơ
N
Chương 7: Quan hệ lớp © 2007 AC - HUT
Ví dụ
void func2(int a, int b) {...}
int xy;
class X {
private:
int x1;
protected:
int x2;
public:
int x3;
int xy;
X(int a, int b, int c)
{
x1 = a;
x2 = b;
x3 = xy = c;
}
void func1(int, int);
void func2(int, int);
};
void X::func1(int i, int j) {...}
void X::func2(int k, int l) {...}
17
©
2
0
0
4
,
H
O
À
N
G
M
I
N
H
S
Ơ
N
Chương 7: Quan hệ lớp © 2007 AC - HUT
class Y:public X {
private:
int y1;
public:
int y2;
int xy;
Y(int d, int e, int f, int g, int h):X(d, e, f)
{
y1 = g;
y2 = xy = h;
}
void func2(int, int);
};
void Y::func2(int m, int n)
{
int a, b; 
x1 = m; //Error, x1 is private in the basic class X
x2 = m; 
x3 = m; 
xy = m; 
X::xy = m; 
::xy = m; 
y1 = n; 
y2 = n;
18
©
2
0
0
4
,
H
O
À
N
G
M
I
N
H
S
Ơ
N
Chương 7: Quan hệ lớp © 2007 AC - HUT
func1(a,b); OK, X::func1(...)
X::func2(a,b); OK, X::func2(...)
::func2(a,b)
}
void f()
{
const int a = 12;
Y objY(3, 4, 5, 6, 7);
objY.x1 = a; //Error, x1 is private
objY.x2 = a; //Error, x2 is protected
objY.x3 = a; 
objY.xy = a; 
objY.y1 = a; //Error, y1 is private
objY.y2 = a;
objY.X::xy = a; 
objY.func1(a, a);
objY.func2(a, a);
}
19
©
2
0
0
4
,
H
O
À
N
G
M
I
N
H
S
Ơ
N
Chương 7: Quan hệ lớp © 2007 AC - HUT
Chuyển ₫ổi kiểu ₫ối tượng
ƒ Một ₫ối tượng hay con trỏ, hoặc tham chiếu ₫ối tượng kiểu lớp dẫn xuất 
sẽ có thể ₫ược chuyển ₫ổi kiểu tự ₫ộng về kiểu lớp cơ sở (nếu ₫ược kế
thừa public) nhưng không ₫ảm bảo theo chiều ngược.
Ví dụ:
class X { ... X(...){...} ... };
class Y:public X { ... Y(...):X(...){...} ... };
X objX(...);
Y objY(...);
X* xp = &objX; //OK
X* xp = &objY; //OK
Y* yp = &objX; //Error
Y* yp = (Y*)&objX; //OK, but not guaranteed!
ƒ Chuyển ₫ổi kiểu tự ₫ộng cho ₫ối tượng có kiểu lớp cơ sở sang kiểu lớp 
dẫn xuất sẽ không thể thực hiện vì không ₫ảm bảo ₫ược quyền truy 
nhập của các thành viên của lớp cơ sở, chắc chắn không ₫ược nếu kế
thừa private. 
20
©
2
0
0
4
,
H
O
À
N
G
M
I
N
H
S
Ơ
N
Chương 7: Quan hệ lớp © 2007 AC - HUT
Chuyển ₫ổi kiểu ₫ối tượng
Ví dụ:
class X {
public:
int x;
};
class Y:private X {
};
void f()
{
Y objY;
X *xp;
xp = &objY; //Error
xp = (X*) &objY; 
xp->x = 5; 
}
21
©
2
0
0
4
,
H
O
À
N
G
M
I
N
H
S
Ơ
N
Chương 7: Quan hệ lớp © 2007 AC - HUT
7.3 Hàm ảo và cơ chế ₫a hình/₫a xạ
ƒ Trong quá trình liên kết, lời gọi các hàm và hàm thành viên 
thông thường ₫ược chuyển thành các lệnh nhảy tới ₫ịa chỉ cụ
thể của mã thực hiện hàm => "liên kết tĩnh"
ƒ Vấn ₫ề thực tế: 
— Các ₫ối tượng ₫a dạng, mặc dù giao diện giống nhau (phép toán 
giống nhau), nhưng cách thực hiện khác nhau => thực thi như thế
nào?
— Một chương trình ứng dụng chứa nhiều kiểu ₫ối tượng (₫ối tượng 
thuộc các lớp khác nhau, có thể có cùng kiểu cơ sở) => quản lý các 
₫ối tượng như thế nào, trong một danh sách hay nhiều danh sách 
khác nhau?
22
©
2
0
0
4
,
H
O
À
N
G
M
I
N
H
S
Ơ
N
Chương 7: Quan hệ lớp © 2007 AC - HUT
Vấn ₫ề của cơ chế "liên kết tĩnh"
ƒ Xem lại chương trình trước, hàm Rectangle::draw ₫ều in ra tên
"Rectangle" => chưa hợp lý nên cần ₫ược ₫ịnh nghĩa lại ở các lớp
dẫn xuất
void Square::draw() {
std::cout << "\nSquare:\t[" << getTL() << getBR() << ']';
}
void TextBox::draw() {
std::cout << "\nTextbox:\t[" << getTL() << getBR() << ' ' 
<< Text << ']';
}
23
©
2
0
0
4
,
H
O
À
N
G
M
I
N
H
S
Ơ
N
Chương 7: Quan hệ lớp © 2007 AC - HUT
Chương trình minh họa 1
void main()
{
Rectangle rect(0,0,50,100);
Square square(0,0,50);
TextBox text("Hello");
rect.draw(); 
square.draw(); 
text.draw(); 
getch(); std::cout << "\n\nNow they are moved...";
rect.move(10,20);
square.move(10,20);
text.move(10,20);
getch(); std::cout << "\n\nNow they are resized...";
rect.resize(2,2);
square.resize(2);
text.resize(2,2);
getch();
}
24
©
2
0
0
4
,
H
O
À
N
G
M
I
N
H
S
Ơ
N
Chương 7: Quan hệ lớp © 2007 AC - HUT
Kết quả: Như ý muốn?
Rectangle: [(0,0)(50,100)]
Square: [(0,0)(50,50)]
Textbox: [(0,0)(10,10) Hello]
Now they are moved...
Rectangle: [(10,20)(60,120)]
Rectangle: [(10,20)(60,70)]
Rectangle: [(10,20)(20,30)]
Now they are resized...
Rectangle: [(20,40)(120,240)]
Rectangle: [(20,40)(120,140)]
Rectangle: [(20,40)(40,60)]
Gọi hàm draw() của Rectangle!
25
©
2
0
0
4
,
H
O
À
N
G
M
I
N
H
S
Ơ
N
Chương 7: Quan hệ lớp © 2007 AC - HUT
Chương trình minh họa 2 
void main()
{
const N =3;
Rectangle rect(0,0,50,100);
Square square(0,0,50);
TextBox text("Hello");
Rectangle* shapes[N] = {&rect, &square, &text};
for (int i = 0; i < N; ++i)
shapes[i]->draw(); 
getch();
}
Quản lý các ₫ối tượng
chung trong một danh sách
nhờ cơ chế dẫn xuất!
Kết quả: các hàm thành viên của lớp dẫn xuất
cũng không ₫ược gọi
Rectangle: [(0,0)(50,100)]
Rectangle: [(0,0)(50,50)]
Rectangle: [(0,0)(10,10)]
26
©
2
0
0
4
,
H
O
À
N
G
M
I
N
H
S
Ơ
N
Chương 7: Quan hệ lớp © 2007 AC - HUT
Giải pháp: Hàm ảo
class Rectangle {
...
public:
...
virtual void draw();
}
27
©
2
0
0
4
,
H
O
À
N
G
M
I
N
H
S
Ơ
N
Chương 7: Quan hệ lớp © 2007 AC - HUT
Kết quả: Nhưmong muốn!
Rectangle: [(0,0)(50,100)]
Square: [(0,0)(50,50)]
Textbox: [(0,0)(10,10) Hello]
Now they are moved...
Rectangle: [(10,20)(60,120)]
Square: [(10,20)(60,70)]
Textbox: [(10,20)(20,30) Hello]
Now they are resized...
Rectangle: [(20,40)(120,240)]
Square: [(20,40)(120,140)]
Textbox: [(20,40)(40,60) Hello]
Chương trình 1
Rectangle: [(0,0)(50,100)]
Square: [(0,0)(50,50)]
Textbox: [(0,0)(10,10) Hello]
Chương trình 2
28
©
2
0
0
4
,
H
O
À
N
G
M
I
N
H
S
Ơ
N
Chương 7: Quan hệ lớp © 2007 AC - HUT
Hàm ảo
class X {
...
public:
virtual void f1() {...} 
virtual void f2() {...} 
virtual void f3() {...} 
void f4() {...} 
};
void function()
{
Y y; 
X* px = &y; //Typ-Convert Y* to X*
px->f1(); //virtual function Y::f1()
px->f2(); //virtual function X::f2()
px->f3(); //virtual function X::f3()
px->f4(); //function X::f4() 
}
class Y:public X {
...
public:
void f1() {...} 
void f2(int a) {...} 
char f3() {...} 
void f4() {...} 
};
29
©
2
0
0
4
,
H
O
À
N
G
M
I
N
H
S
Ơ
N
Chương 7: Quan hệ lớp © 2007 AC - HUT
Ví dụ hàm ảo
class X {
protected:
int x;
public:
X(int x_init) { x = x_init;}
virtual void print();
};
class Y:public X {
protected:
int y;
public:
Y(int x_init, int y_init):X(x_init) {y = y_init;}
void print();
};
class Z:public Y {
protected:
int z;
public:
Z(int x_init, int y_init, int z_init):Y(x_init, y_init)
{z = z_init;}
void print();
};
30
©
2
0
0
4
,
H
O
À
N
G
M
I
N
H
S
Ơ
N
Chương 7: Quan hệ lớp © 2007 AC - HUT
class U:public Y {
protected:
int u;
public:
Z(int x_init, int y_init, int u_init):Y(x_init, y_init)
{u = u_init;}
void print();
};
void X::print()
{
cout << “Data of Class X: “ << x << endl;
}
void Y::print()
{
cout << “Data of Class X+Y: “ << x + y << endl;
}
void Z::print()
{
cout << “Data of Class X+Y+Z: “ << x + y + z << endl;
}
void U::print()
{
cout << “Data of Class X+Y+U: “ << x + y + u << endl;
}
31
©
2
0
0
4
,
H
O
À
N
G
M
I
N
H
S
Ơ
N
Chương 7: Quan hệ lớp © 2007 AC - HUT
void print_data(X* px)
{
px->print();
}
main()
{
X* pobjX = new X(1);
Y* pobjY = new Y(10, 20);
Z* pobjZ = new Z(100, 200, 300);
U* pobjU = new U(1000, 2000, 3000);
print_data(pobjX);
print_data(pobjY);
print_data(pobjZ);
print_data(pobjU);
delete pobjX;
delete pobjY;
delete pobjZ;
delete pobjU;
}
main()
{
int x;
X *pobj[4];
pobj[0] = new X(1);
pobj[1] = new Y(10, 20);
pobj[2] = new Z(100, 200, 300);
pobj[3] = new U(1000, 2000, 3000);
for(x = 0; x < 4; x++)
print_data(pobj[x]);
delete[4] pobj;
}
Data of Class X: 1
Data of Class X+Y: 30
Data of Class X+Y+Z: 600
Data of Class X+Y+U: 6000
Kết quả:
32
©
2
0
0
4
,
H
O
À
N
G
M
I
N
H
S
Ơ
N
Chương 7: Quan hệ lớp © 2007 AC - HUT
7.4 Ví dụ thư viện khối chức năng
ƒ Bài toán: 
— Xây dựng một thư viện các khối chức năng phục vụ tính toán và
mô phỏng tương tự trong SIMULINK
— Viết chương trình minh họa sử dụng ₫ơn giản
ƒ Ví dụ một sơ ₫ồ khối
StaticGain Limiter IntegratorSum0
33
©
2
0
0
4
,
H
O
À
N
G
M
I
N
H
S
Ơ
N
Chương 7: Quan hệ lớp © 2007 AC - HUT
Biểu ₫ồ lớp

File đính kèm:

  • pdfC7_Class_Relationship.pdf