Bài 7: Đa hình
ớ
ệ
Gi
i thi u
ả • Đa hình là kh năng cho phép:
•
ứ
c nh ngh a các ph
ươ ố
ĩ ể
ệ đị
ng th c trùng ể ả ng và ki u tham s , cùng ki u tr ế ớ ng th c trùng nhau c a các l p k ươ
ứ ự ạ
ứ
ồ
ớ đượ đị Cho phép các l p ố ượ nhau: cùng tên, cùng s l ươ ề v . Vi c nh ngh a ph ọ ừ th a nhau còn
ủ ng th c.
ĩ đượ c g i là s n p ch ng ph
•
ươ
đố ượ i t
ứ ủ ớ ươ
ự ươ ng th c c a l p t
đ ng ang ng
ng th c trùng tên, d a vào ệ ả
ứ ẽ ự ng trình s th c hi n ph ế
ươ đ
ẽ
ọ Khi g i các ph ọ g i mà ch ứ ng, và do ó, s cho các k t qu khác nhau.
•
ớ
ườ ớ ươ
ụ ươ
ự ứ
ứ
Ví d : Xây d ng l p ng có ph
ng th c Nhap() và ph
ớ i, l p sinh viên, l p giáo viên cùng ng th c Xuat().
để ử
ươ
ớ
ơ ở
ế x lý ư ng c a t t c các l p trong m t phân c p nh i mà
ng trình ộ đ ệ đượ i p
ấ ử đ c g i
Nh v y a hình là kh n ng cho phép vi t ch ư ậ đ ổ t ng quát các đố ượ i t các ầ không c n bi t
đố ượ i t ủ ớ ng c a l p c s . Do v y m t thông ậ ế đố ượ i t
ả ă ủ ấ ả ộ ậ ộ ớ ng nh n thu c l p nào.
ươ
Các ph
ứ ả ng th c o
•
Xét ví dụ ớ
ề
ứ
ươ
ng th c xuat() ỏ ể
ố ượ ố ượ ố ượ
ể ng ki u A ể ng ki u B ể ng ki u c
ệ
ả
ươ
ứ ả
3 l p A,B,C đ u có ph A *p, *q, *r; // p, q, r là con tr ki u A A a; // a là đ i t B b; // b là đ i t C c; // c là đ i t // p = &a ; q = &b ; r = &c ; // p>xuat(); q>xuat(); r>xuat(); ề ả (cid:222) C ba câu l nh đ u g i đ n A::xuat() (cid:222) Gi
ọ ế ự i pháp: Xây d ng xuat() là ph
ng th c o
ươ
Các ph
ứ ả ng th c o
ả ử
ẫ
ớ
ươ s các l p này đ u có ph ứ
ả ử ể ị
ng th c xuat(). ả
ớ ơ ở • Gi s A là l p c s . ấ ớ • B,C,D là l p d n xu t. ề • Gi ươ • Đ đ nh nghĩa các ph
ứ ng th c này là o có 2 cách:
ừ
đề ủ
c a
ươ
ĩ ớ
ơ ở
đị
ứ
ph
đề
bên
ặ o Ho c thêm t khoá virtual vào dòng tiêu ng th c bên trong nh ngh a l p c s A. ặ o Ho c thêm t khoá virtual vào dòng tiêu đị
ừ ĩ ủ
ấ ả
ớ
trong nh ngh a c a t t c các l p A, B, C và D
ươ
Các ph
ứ ả ng th c o
ộ ấ
ự
ấ
ườ ậ
i l p
ủ ớ
ẩ
ị
• Khi xây d ng m t c u trúc cây phân c p, ng trình chu n b các hành vi chung c a l p đó.
ẽ ượ
ể ể ệ
• Hành vi giao ti p chung s đ
c dùng đ th hi n đó ộ
ế ư ứ ả
ươ
cùng hành vi, nh ng có các hành đ ng khác nhau là ph
ng th c o.
ụ ọ
ụ
Ví d : Đ c thêm ví d trang 122 giáo trình LTHĐT
ươ
Các ph
cout< <"class Base"< ỏ ỉ n ph ứ
ặ ớ đế
ủ ớ ươ ng trình. ươ
//(c a l p Base ho c l p
Derived) //tùy vào lúc ch y ạ
ch
} int main()
{
Base *B=new Base;
Derived *D=new Derived;
B>Display(); //Base::Display()
D>Display(); //Derived::Display()
Show(B); //Base::Display()
Show(D); //Derived::Display()
return 0;
} class Base
{
public:
virtual void Display()
{
}
};
void Show(Base *B)
{
B>Display(); //Con tr B ch
ng th c Display() ế ạ ươ ng trình: • K t qu khi ch y ch
ả • ả Gi • i thích:
N u không có khai báo virtual cho ph
ế
ng th c
ệ
khi đó l nh Show(D) trong hàm main() s g i đ n
ố ượ
(vì đ i t ứ Base::Display()
ươ
ẽ ọ ế Base::Display()
ố ượ ủ ớ ơ ở ủ ớ ẫ ấ ng c a l p d n xu t cũng là đ i t ng c a l p c s ). ờ ng th c virtual cho ph ự ươ ứ ọ ươ
ng th c
ộ ố ể ủ
ố ươ ề ứ Base::Display() nên s ẽ
ộ
ứ Base::Display() m t cách c ng
Show() mà tùy thu c vào ki u c a tham s vào lúc
ng trình. ( khi truy n tham s B thì Base::Display() • Nh khai báo
ệ
không th c hi n g i ph
ắ
nh c trong hàm
ạ
ch y ch
ượ ọ
đ ượ ọ ề c g i, khi truy n D thì Derived::Display() đ c g i). • Gi • ậ ẽ
ấ ủ ủ ớ
ả ộ ớ ơ ở
virtual trong l p c s , trình biên
ớ
ơ ở
ẫ
ng c a l p c s và l p d n
ứ ả
ươ
ỉ ế
ng th c o ỏ ấ
Khi nh n th y có khai báo
ỗ ố ượ
ị
d ch s thêm vào m i đ i t
ỏ
xu t c a nó m t con tr ch đ n b ng ph
(virtual function table), con tr có tên vptr. • ươ ứ ả ạ ơ ỏ ng th c o là n i ch a các con tr ch đ n đo n ị ứ ươ ỉ ế
ứ ả ứ
ớ ả
B ng ph
ươ
ch ng trình đã biên d ch ng v i các ph ng th c o. • • ỗ ớ ứ ả ứ ả ng th c o.
ươ
ế ạ ệ ạ
ươ ỉ ậ
ng c a l p. Đ n khi ch
ớ ượ ố ượ ủ ắ ầ
ng th c o khi b t đ u có
ươ
ng trình ch y,
ố ế
c n i k t và thi ng m i đ M i l p có m t b ng ph
ươ
ộ ả
ả
ị
Trình biên d ch ch l p b ng ph
ủ ớ
ố ượ
vi c t o đ i t
ứ ả
ph
ng th c o c a đ i t
hành thông qua con tr vptr ỏ • Gi • Xét ví d trên: Hàm Show(D). • ể ể ổ ng ố ượ D thu c l p ộ ố ượ • ộ ố ượ Đ i t
thành m t đ i t
ố
toàn gi ng m t đ i t ị
ộ ớ Derived tuy b chuy n đ i ki u
ộ ớ Base nh ng nó không hoàn
ư
ng thu c l p
ố
ng c a ủ Base chính c ng nh ư B. ỉ ế ươ ứ ả ị B ch đ n v trí trên b ng ph ỏ
o ng v i ph ng th c
ẫ ng th c
ứ Base::Display(), trong khi con tr ỏ
ứ
th c ươ
trong D v n ế
ch đ n ph
ể còn
ị ỉ
ể Con tr vptr trong
ớ
ả ứ
ươ
vptr
Derived::Display() cho dù D b chuy n ki u thành ng
Base. ậ ế ươ ệ
l nh: ng ứ
th c ọ
Show(D);g i đ n ph Do v y
Derived::Display() ng th c o. ươ ứ ả ể ươ • Ph ng th c o không th là các ph ứ
ng th c tĩnh. ầ ừ ướ • Không c n thi c ộ t ph i ghi rõ t
ươ khóa virtual tr
ấ ứ ả ẫ ớ ị ế
đ nh nghĩa m t ph ả
ng th c o trong l p d n xu t. ị ươ ả • Khi m t ph ứ
ng th c đ c đ nh nghĩa là o, t ả ị ẫ ả ề ấ ề
ế ơ ươ
ươ ẽ ể ị ừ ớ
ượ
ộ
l p
ố
ấ ề
ơ ở ế ớ
c s đ n l p d n xu t đ u ph i đ nh nghĩa th ng
ố
ể
nh t v tên, ki u tr v và danh sách các tham s .
ứ
ấ ị
N u ta s xu t đ nh nghĩa ph
ng th c khác đi thì
ứ
ng th c khác.
trình biên d ch s hi u đó là ph • ố ượ ể ạ ế ế ướ
t k h ng đ i t ườ ậ
i l p trình ph i đoán tr
ọ ệ ố
ướ ự
ợ ữ ả
ng, đ t o h th ng ph
ả
c s phát
đó l a ch n nh ng thành viên phù h p cho Trong quá trình thi
ế ừ
ệ
h mang tính k th a cao ng
ự
ừ
ủ ấ
ể
tri n c a c u trúc t
ớ
l p trên cùng. • ể ự ớ ớ
t k các l p có các ph ố ượ ể ạ ạ
ố ượ
Đ tránh tình tr ng xây d ng các đ i t
ươ
ế ế
cho phép thi
và cũng không th t o ra đ i t ộ
ng lãng phí b nh , C++
ả
ứ ả
ng th c o không làm gì c ,
ủ ớ
ng c a l p đó. ừ ượ ữ ọ ớ ớ Nh ng l p nh v y g i là l p tr u t
ư ậ ng. • Là l p ch dùng làm c s cho các l p khác. • Không đ
ng. • Các ph
ứ ả • B t k l p nào d n xu t t • ầ • ư ả ớ
ơ ể ạ ọ ớ ủ ượ ạ ộ ặ ắ ở ấ
c t o ra kh p n i đ t o b m t chung cho m i l p c a ứ ả ượ ườ ươ ể Trong cây phân c p trên không ph i l p nào cũng c n hàm print(),
nh ng nó đ
cây phân c p.ấ
A::Print() th ng th c o đ có đ c tính đa hình. ng là ph • Khi đó v i hàmớ void Show(A* a)
{ a>Print(); ề ể
ọ ế ố ượ
ơ ủ ợ ố • ủ ể
ứ
ư ế ị đố ượ
i t ầ ả ươ ự ớ ộ ớ
ng thu c l p A, ta
ứ
ng th c thu n o ạ
ng v i các ph class A
{ public:
virtual void Print() = 0; }; ừ
ư }
A, B, C, D ho c ặ E) mà
ng đ ki u cho nó (
ta có th truy n đ i t
ể
ẫ
v n g i đ n đúng phu ng th c Print() phù h p, dù ki u c a đ i
ẫ
ượ
t.
ng lúc biên d ch v n còn ch a bi
t
ạ
Để
tránh trình tr ng vô tình t o ra
ượ
ớ
ườ
th
ng xây d ng l p tr u t
(pure virtual function) nh sau: ụ Xem ví d trang 126 giáo trình LTHDT Ø Chú ý: • ể ạ ừ ượ ư ộ ố ượ
ộ • ộ ả ộ ớ ố ượ ớ ị l p tr u t ế ừ ừ ớ
ầ ả
ứ
ầ ả ủ ớ ơ ở ẫ ấ ừ ượ
ng chúng ta không đ nh
ẽ
ế ừ
ng th c thu n o, do tính k th a nó s bao hàm
ẽ
ớ
ng th c thu n o c a l p c s , nên l p d n xu t này s • ươ
ứ
ớ ng. ừ ượ ơ ở ừ ượ ừ ượ
ớ
ế
ng) chúng ta đ nh nghĩa thêm m t ph ấ ừ
ớ
ng, n u trong l p d n xu t (t
ươ
ng ẫ
ộ
ừ ượ ị
ẽ ở ầ ả ứ ớ ớ ủ ớ
ng c a l p tr u t
ng,
Chúng ta không th t o ra m t đ i t
ỏ ỏ ế ớ
ể ạ
nh ng hoàn toàn có th t o ra m t con tr tr đ n l p này (vì
ặ
ỏ
ng thu c l p) ho c là m t tham
con tr không ph i là đ i t
chi u.ế
ế
N u trong l p k th a t
nghĩa ph
ươ
ph
ở
tr thành l p tr u t
ị
Theo đ nh nghĩa l p tr u t
ớ
l p c s tr u t
th c thu n o khác, l p này cũng s tr thành l p tr u t ng. • • ử ả Các toán t ươ ng th c nên ta có th đ nh ả ử ụ ứ
ạ ể ị
là o, chú ý ki u c a toán h ng ph i s d ng • ấ
ử ả
ể ủ ớ ơ ở ố b n ch t cũng là các ph
ể ủ
ử ả
o. o:
ử ả
Các toán t
nghĩa các toán t
ki u c a l p c s g c có toán t
Ví dụ class A
{ …
virtual A& operator + (A& T);
virtual A& operator = (A& T);
… }
Class B: public A
{…
virtual A& operator + (A& T);
virtual A& operator = (A& T);
… }ứ ả
ng th c o
class Derived : public Base
{
public:
virtual void Display()
{
cout<<"class Derived"<
ươ
Các ph
ứ ả
ng th c o
ươ
Các ph
ứ ả
ng th c o
ả
ơ ế
i thích c ch :
ươ
Các ph
ứ ả
ng th c o
ả
ơ ế
i thích c ch :
ụ
ươ
Các ph
ứ ả
ng th c o
ủ
ặ
ươ
ứ ả
ư
• Đ c tr ng c a ph
ớ ơ ở ừ ượ
L p c s tr u t
ng
ớ ơ ở ừ ượ
ng
L p c s tr u t
ớ
ơ ở
ỉ
ớ
ượ
ộ ố ượ
ở ạ
ừ
c kh i t o m t đ i t
ộ ớ
ng thu c l p tr u
ượ
t
ừ ượ
ươ
ng là các ph
ng
ứ ủ ớ
ng th c c a l p tr u t
ầ
ươ
th c o thu n túy.
ươ
virtual void tên_ph
ứ
ng_th c() = 0 ;
ấ ừ ộ ớ ớ ở ừ ượ
m t l p c s tr u t
ầ ả
ươ
ứ
ạ ấ ả
ng
ng th c thu n o mà
t c các ph
ẫ
i t
ấ ỳ ớ
ả ị
ph i đ nh nghĩa l
ừ ưở
nó th a h
ng.
ớ ơ ở ừ ượ
L p c s tr u t
ng
ớ ơ ở ừ ượ
L p c s tr u t
ng
ớ ơ ở ừ ượ
L p c s tr u t
ng
ả ủ
ộ ớ
Các thành viên o c a m t l p