Professional Documents
Culture Documents
Chuong - 09 - Thua Ke
Chuong - 09 - Thua Ke
Chuong - 09 - Thua Ke
Tha k
Trong thc t hu ht cc lp c th k tha t cc lp c trc m khng cn nh ngha li mi hon ton. V d xem xt mt lp c t tn l RecFile i din cho mt tp tin gm nhiu mu tin v mt lp khc c t tn l SortedRecFile i din cho mt tp tin gm nhiu mu tin c sp xp. Hai lp ny c th c nhiu im chung. V d, chng c th c cc thnh vin hm ging nhau nh l Insert, Delete, v Find, cng nh l thnh vin d liu ging nhau. SortedRecFile l mt phin bn c bit ca RecFile vi thuc tnh cc mu tin ca n c t chc theo th t c thm vo. V th hu ht cc hm thnh vin trong c hai lp l ging nhau trong khi mt vi hm m ph thuc vo yu t tp tin c sp xp th c th khc nhau. V d, hm Find c th l khc trong lp SortedRecFile bi v n c th nh vo yu t thun li l tp tin c sp thc hin tm kim nh phn thay v tm tuyn tnh nh hm Find ca lp RecFile. Vi cc thuc tnh c chia s ca hai lp ny th vic nh ngha chng mt cch c lp l rt di dng. R rng iu ny dn ti vic phi sao chp li m ng k. M khng ch mt thi gian lu hn vit n m cn kh c th c bo tr hn: mt thay i ti bt k thuc tnh chia s no c th phi c sa i ti c hai lp. Lp trnh hng i tng cung cp mt k thut thun li gi l tha k gii quyt vn ny. Vi tha k th mt lp c th tha k nhng thuc tnh ca mt lp c trc. Chng ta c th s dng tha k nh ngha nhng thay i ca mt lp m khng cn nh ngha li lp mi t u. Cc thuc tnh chia s ch c nh ngha mt ln v c s dng li khi cn. Trong C++ tha k c h tr bi cc lp dn xut (derived class). Lp dn xut th ging nh lp gc ngoi tr nh ngha ca n da trn mt hay nhiu lp c sn c gi l lp c s (base class). Lp dn xut c th chia s nhng thuc tnh chn (cc thnh vin hm hay cc thnh vin d liu) ca cc lp c s ca n nhng khng lm chuyn i nh ngha ca bt k lp c s no. Lp dn xut chnh n c th l lp c s ca mt lp dn xut khc. Quan h tha k gia cc lp ca mt chng trnh c gi l quan h cp bc lp (class hierarchy). Lp dn xut cng c gi l lp con (subclass) bi v n tr thnh cp thp hn ca lp c s trong quan h cp bc. Tng t mt lp c s c th c gi l lp cha (superclass) bi v t n c nhiu lp khc c th c dn xut.
Chng 9: Tha k
148
9.1. V d minh ha
Chng ta s nh ngha hai lp nhm mc ch minh ha mt s khi nim lp trnh trong cc phn sau ca chng ny. Hai lp c nh ngha trong Danh sch 9.1 v h tr vic to ra mt th mc cc i tc c nhn.
Danh sch 9.1 1 #include <iostream.h> 2 #include <string.h> 3 class Contact { 4 public: 5 Contact(const char *name, const char *address, const char *tel); 6 ~Contact (void); 7 const char*Name (void) const {return name;} 8 const char*Address(void) const {return address;} 9 const char*Tel(void) const {return tel;} 10 friend ostream& operator << (ostream&, Contact&); 11 private: 12 char *name; // ten doi tac 13 char *address; // dia chi doi tac 14 char *tel; // so dien thoai 15 }; 16 //------------------------------------------------------------------17 class ContactDir { 18 public: 19 ContactDir(const int maxSize); 20 ~ContactDir(void); 21 void Insert(const Contact&); 22 void Delete(const char *name); 23 Contact* Find(const char *name); 24 friend ostream& operator <<(ostream&, ContactDir&); 25 private: 26 int Lookup(const char *name); 27 Contact **contacts;// danh sach cac doi tac int dirSize; // kich thuoc thu muc hien tai 28 int maxSize; // kich thuoc thu muc toi da 29 };
Ch gii
Lp Contact lu gi cc chi tit ca mt i tc (ngha l, tn, a ch, v s in thoi). 18 Lp ContactDir cho php chng ta thm, xa, v tm kim mt danh sch cc i tc. 22 Hm Insert xen mt i tc mi vo th mc. iu ny s vit chng ln mt i tc tn ti (nu c) vi tn ging nhau. 23 Hm Delete xa mt i tc (nu c) m tn ca i tc trng vi tn cho.
Chng 9: Tha k
149
24 Hm Find tr v mt con tr ti mt i tc (nu c) m tn ca i tc khp vi tn cho. 27 Hm Lookup tr v ch s v tr ca mt i tc m tn ca i tc khp vi tn cho. Nu khng tn ti th sau hm Lookup tr v ch s ca v tr m ti m mt u vo nh th s c thm vo. Hm Lookup c nh ngha nh l ring (private) bi v n l mt hm ph c s dng bi cc hm Insert, Delete, v Find. Ci t ca hm thnh vin v hm bn nh sau:
Contact::Contact (const char *name, const char *address, const char *tel) { Contact::name = new char[strlen(name) + 1]; Contact::address = new char[strlen(address) + 1]; Contact::tel = new char[strlen(tel) + 1]; strcpy(Contact::name, name); strcpy(Contact::address, address); strcpy(Contact::tel, tel); } Contact::~Contact (void) { delete name; delete address; delete tel; } ostream& operator << (ostream &os, Contact &c) { os << "(" << c.name << " , " << c.address << " , " << c.tel << ")"; return os; } ContactDir::ContactDir (const int max) { typedef Contact *ContactPtr; dirSize = 0; maxSize = max; contacts = new ContactPtr[maxSize]; }; ContactDir::~ContactDir (void) { for (register i = 0; i < dirSize; ++i) delete contacts[i]; delete [] contacts; } void ContactDir::Insert (const Contact& c) { if (dirSize < maxSize) { int idx = Lookup(c.Name()); if (idx > 0 && strcmp(c.Name(), contacts[idx]->Name()) == 0) { delete contacts[idx];
Chng 9: Tha k
150
} else { for (register i = dirSize; i > idx; --i) // dich phai contacts[i] = contacts[i-1]; ++dirSize; } contacts[idx] = new Contact(c.Name(), c.Address(), c.Tel());
void ContactDir::Delete (const char *name) { int idx = Lookup(name); if (idx < dirSize) { delete contacts[idx]; --dirSize; for (register i = idx; i < dirSize; ++i) contacts[i] = contacts[i+1]; } }
// dich trai
Contact *ContactDir::Find (const char *name) { int idx = Lookup(name); return (idx < dirSize && strcmp(contacts[idx]->Name(), name) == 0) ? contacts[idx] : 0; } int ContactDir::Lookup (const char *name) { for (register i = 0; i < dirSize; ++i) if (strcmp(contacts[i]->Name(), name) == 0) return i; return dirSize; } ostream &operator << (ostream &os, ContactDir &c) { for (register i = 0; i < c.dirSize; ++i) os << *(c.contacts[i]) << '\n'; return os; }
Chng 9: Tha k
151
};
3 4 5 7
Phn u ca lp dn xut chn vo cc lp c s m n tha k. Mt du hai chm (:) phn bit gia hai phn. y, lp ContactDir c c t l lp c s m lp SmartDir c dn xut. T kha public pha trc lp ContactDir ch nh rng lp ContactDir c s dng nh mt lp c s chung. Lp SmartDir c hm xy dng ca n, hm xy dng ny triu gi hm xy dng ca lp c s trong danh sch khi to thnh vin ca n. Hm Recent tr v mt con tr ti i tc c tm kim sau cng (hoc 0 nu khng c). Hm Find c nh ngha li sao cho n c th ghi nhn u vo c tm kim sau cng. Con tr recent c t ti tn ca u vo c tm sau cng.
152
Chng 9: Tha k
Bi v lp ContactDir l mt lp c s chung ca lp SmartDir nn tt c thnh vin chung ca lp ContactDir tr thnh cc thnh vin chung ca lp martDir. iu ny ngha l chng ta c th triu gi mt hm thnh vin nh l Insert trn mt i tng SmartDir v y l mt li gi ti ContactDir::Insert. Tng t, tt c cc thnh vin ring ca lp ContactDir tr thnh cc thnh vin ring ca lp SmartDir. Ph hp vi cc nguyn l n thng tin, cc thnh vin ring ca lp ContactDir s khng th c truy xut bi SmartDir. V th, lp SmartDir s khng th truy xut ti bt k thnh vin d liu no ca lp ContactDir cng nh l hm thnh vin ring Lookup. Lp SmartDir nh ngha li hm thnh vin Find. iu ny khng nn nhm ln vi ti nh ngha. C hai nh ngha phn bit ca hm ny: ContactDir::Find v SmartDir::Find (c hai nh ngha c cng du hiu du cho chng c th c cc du hiu khc nhau nu c yu cu). Triu gi hm Find trn i tng SmartDir th hai s c gi. Nh c minh ha bi nh ngha ca hm Find trong lp SmartDir,hm th nht c th vn cn c triu gi bng cch s dng tn y ca n. on m sau minh ha lp SmartDir c x nh l lp ContactDir nhng cng theo di u vo c tm kim c gn nht:
SmartDir dir(10); dir.Insert(Contact("Mary", "11 South Rd", "282 1324")); dir.Insert(Contact("Peter", "9 Port Rd", "678 9862")); dir.Insert(Contact("Jane", "321 Yara Ln", "982 6252")); dir.Insert(Contact("Fred", "2 High St", "458 2324")); dir.Find("Jane"); dir.Find("Peter"); cout << "Recent: " << *dir.Recent() << '\n';
iu ny s cho ra kt qu sau:
Recent: (Peter , 9 Port Rd , 678 9862)
Mt i tng kiu SmartDir cha ng tt c d liu thnh vin ca ContactDir cng nh l bt k d liu thnh vin thm vo c gii thiu bi
Chng 9: Tha k
153
9.3. K hiu th bc lp
Th bc lp thng c minh ha bng cch s dng k hiu ha n gin. Hnh 9.2 minh ha k hiu ca ngn ng UML m chng ta s ang s dng trong gio trnh ny. Mi lp c biu din bng mt hp c gn nhn l tn lp. Tha k gia hai lp c minh ha bng mt mi tn c hng v t lp dn xut n lp c s. Mt ng thng vi hnh kim cng mt u miu t composition (tm dch l quan h b phn, ngha l mt i tng ca lp c bao gm mt hay nhiu i tng ca lp khc). S i tng cha bi i tng khc c miu t bi mt nhn (v d, n).
Hnh 9.2 Mt th bc lp n gin
ContactDir
Contact
Sm artDir
Hnh 9.2 c thng dch nh sau. Contact, ContactDir, v SmartDir l cc lp. Lp ContactDir gm c khng hay nhiu i tng Contact. Lp SmartDir c dn xut t lp ContactDir.
9.4. Hm xy dng v hm hy
Lp dn xut c th c cc hm xy dng v mt hm hy. Bi v mt lp dn xut c th cung cp cc d liu thnh vin da trn cc d liu thnh vin t lp c s ca n nn vai tr ca hm xy dng v hm hy l khi to v hy b cc thnh vin thm vo ny. Khi mt i tng ca mt lp dn xut c to ra th hm xy dng ca lp c s c p dng ti n trc tin v theo sau l hm xy dng ca lp dn xut. Khi mt i tng b thu hi th hm hy ca lp dn xut c p dng trc tin v sau l hm hy ca lp c s. Ni cch khc th cc hm xy dng c ng dng theo th t t gc (lp cha) n ngn (lp con)
Chng 9: Tha k
154
v cc hm hy c p dng theo th t ngc li. V d xem xt mt lp C c dn xut t lp B, m lp B li c dn xut t lp A. Hnh 9.3 minh ha mt i tng c thuc lp C c to ra v hy b nh th no.
class A class B : public A class C : public B { /* ... */ } { /* ... */ } { /* ... */ }
Hnh 9.3
A::A
A::~A
B::B
B::~B
C::C
.........
C::~C
Bi v hm xy dng ca lp c s yu cu cc i s, chng cn c ch nh trong phn nh ngha hm xy dng ca lp dn xut. lm cng vic ny, hm xy dng ca lp dn xut triu gi r rng hm xy dng lp c s trong danh sch khi to thnh vin ca n. V d, hm xy dng SmartDir truyn i s ca n ti hm xy dng ContactDir theo cch ny:
SmartDir::SmartDir (const int max) : ContactDir(max) { /* ... */ }
Thng thng, tt c nhng g m mt hm xy dng lp dn xut yu cu l mt i tng t lp c s. Trong mt vi tnh hung, iu ny thm ch c th khng cn tham kho ti hm xy dng lp c s:
extern ContactDir cd; // c nh ngha u SmartDir::SmartDir (const int max) : cd { /* ... */ }
Mc d cc thnh vin ring ca mt lp lp c s c tha k bi mt lp dn xut nhng chng khng th c truy xut. V d, lp SmartDir tha k tt c cc thnh vin ring (v chung) ca lp ContactDir nhng khng c php tham kho trc tip ti cc thnh vin ring ca lp ContactDir. tng l cc thnh vin ring nn c che du hon ton sao cho chng khng th b can thip vo bi cc khch hng (client) ca lp. S gii hn ny c th chng t chiu hng ngn cm cc lp c kh nng l lp c s cho nhng lp khc. Vic t chi truy xut ca lp dn xut ti cc thnh vin ring ca lp c s vng vo s ci t n hay thm ch lm cho vic nh ngha n l khng thc t. S gii hn c th c gii phng bng cch nh ngha cc thnh vin ring ca lp c s nh l c bo v (protected). n khi cc khch hng ca lp c xem xt, mt thnh vin c bo v th ging nh mt thnh vin ring: n khng th c truy xut bi cc khch hng lp. Tuy nhin,
Chng 9: Tha k
155
mt thnh vin lp c s c bo v c th c truy xut bi bt k lp no c dn xut t n. V d, cc thnh vin ring ca lp ContactDir c th c to ra l c bo v bng cch thay th t kha protected cho t kha private:
class ContactDir { //... protected: int Lookup (const char *name); Contact **contacts;// danh sach cac doi tac int dirSize; // kich thuoc thu muc hien tai int maxSize; // kich thuoc thu muc toi da };
Kt qu l, hm Lookup v cc thnh vin d liu ca lp ContactDir by gi c th truy xut bi lp SmartDir. Cc t kha truy xut private, public, v protected c th xut hin nhiu ln trong mt nh ngha lp. Mi t kha truy xut ch nh cc c im truy xut ca cc thnh vin theo sau n cho n khi bt gp mt t kha truy xut khc:
class Foo { public: // cac thanh vien chung... private: // cac thanh vien rieng... protected: // cac thanh vien duoc bao ve... public: // cac thanh vien chung nua... protected: // cac thanh vien duoc bao ve nua... };
Chng 9: Tha k
156
Tt c cc thnh vin ca mt lp c s ring tr thnh cc thnh vin ring ca lp dn xut. V th tt c x, Fx, y, Fy, z, v Fz tr thnh cc thnh vin ring ca B v C. Cc thnh vin ca lp c s chung gi cc c im truy xut ca chng trong lp dn xut. V th, x v Fx tr thnh cc thnh vin ring D, y v Fy tr thnh cc thnh vin chung ca D, v z v Fz tr thnh cc thnh vin c bo v ca D. Cc thnh vin ring ca lp c s c bo v tr thnh cc thnh vin ring ca lp dn xut. Nhng ngc li, cc thnh vin chung v c bo v ca lp c s c bo v tr thnh cc thnh vin c bo v ca lp dn xut. V th, x v Fx tr thnh cc thnh vin ring ca E, v y, Fy, z, v Fz tr thnh cc thnh vin c bo v ca E.
Bng 9.1
Chng ta cng c th min cho mt thnh vin ring l ca lp c s t nhng chuyn i truy xut c c t bi mt lp dn sao cho n vn gi li nhng c im truy xut gc ca n. lm iu ny, cc thnh vin c min c t tn y trong lp dn xut vi c im truy xut gc ca n. V d:
class C : private A { //... public: A::Fy; // lam cho Fy la mot thanh vien chung cua C protected: A::z; // lam cho z la mot thanh vien duoc bao ve // cua C };
9.6. Hm o
Xem xt s thay i khc ca lp ContactDir c gi l SortedDir, m m bo rng cc i tc mi c xen vo phn cn li ca danh sch c sp xp. Thun li r rng ca iu ny l tc tm kim c th c ci thin bng cch s dng gii thut tm kim nh phn thay v tm kim tuyn tnh. Vic tm kim trong thc t c thc hin bi hm thnh vin Lookup. V th chng ta cn nh ngha li hm ny trong lp SortedDir sao cho n s dng gii thut tm kim nh phn. Tuy nhin, tt c cc hm thnh vin khc tham kho ti ContactDir::Lookup. Chng ta cng c th nh ngha cc hm ny sao cho chng tham kho ti SortedDir::Lookup. Nu chng ta theo tip cn ny, gi tr ca tha k tr nn ng ng hn bi v thc t chng ta c th phi nh ngha li ton b lp.
Chng 9: Tha k
157
Thc s ci m chng ta mun lm l tm cch biu din iu ny: hm Lookup nn c lin kt ti kiu ca i tng m triu gi n. Nu i tng thuc kiu SortedDir sau triu gi Lookup (t bt k ch no, thm ch t bn trong cc hm thnh vin ca ContactDir) c ngha l SortedDir::Lookup. Tng t, nu i tng thuc kiu ContactDir sau gi Lookup (t bt k ch no) c ngha l ContactDir::Lookup. iu ny c th c thc thi thng qua lin kt ng (dynamic binding) ca hm Lookup: s quyt nh chn phin bn no ca hm Lookup gi c to ra thi gian chy ph thuc vo kiu ca i tng. Trong C++, lin kt ng c h tr thng qua cc hm thnh vin o. Mt hm thnh vin c khai bo nh l o bng cch chn thm t kha virtual trc nguyn mu (prototype) ca n trong lp c s. Bt k hm thnh vin no, k c hm xy dng v hm hy, c th c khai bo nh o. Hm Lookup nn c khai bo nh o trong lp ContactDir:
class ContactDir { //... public: virtual int //... };
Ch cc hm thnh vin khng tnh c th c khai bo nh l o. Mt hm thnh vin o c nh ngha li trong mt lp dn xut phi c chnh xc cng tham s v kiu tr v nh mt hm thnh vin trong lp c s. Cc hm o c th c ti nh ngha ging nh cc thnh vin khc. Danh sch 9.3 trnh by nh ngha ca lp SortedDir nh lp dn xut ca lp ContactDir.
Danh sch 9.3 1 class SortedDir : public ContactDir { 2 public: 3 SortedDir (const int max) : ContactDir(max) {} 4 public: 5 virtual int Lookup (const char *name); 6 }; Ch gii
3 5
Hm xy dng n gin ch gi hm xy dng lp c s. Hm Lookup c khai bo li nh l o cho php bt k lp no c dn xut t lp SortedDir nh ngha li n. nh ngha mi ca hm Lookup nh sau:
int SortedDir::Lookup (const char *name) { int bot = 0; int top = dirSize - 1;
Chng 9: Tha k
158
int pos = 0; int mid, cmp; while (bot <= top) { mid = (bot + top) / 2; if ((cmp = strcmp(name, contacts[mid]->Name())) == 0) return mid; else if (cmp < 0) pos = top = mid - 1; // gioi han tim tren nua thap hon else pos = bot = mid + 1; // gioi han tim tren nua cao hon } return pos < 0 ? 0 : pos;
on m sau minh ha rng hm SortedDir::Lookup c gi bi hm ContactDir::Insert khi c triu gi thng qua i tng SortedDir:
SortedDir dir(10); dir.Insert(Contact("Mary", "11 South Rd", "282 1324")); dir.Insert(Contact("Peter", "9 Port Rd", "678 9862")); dir.Insert(Contact("Jane", "321 Yara Ln", "982 6252")); dir.Insert(Contact("Jack", "42 Wayne St", "663 2989")); dir.Insert(Contact("Fred", "2 High St", "458 2324")); cout << dir;
N s cho ra kt qu sau:
(Fred , 2 High St , 458 2324) (Jack , 42 Wayne St , 663 2989) (Jane , 321 Yara Ln , 982 6252) (Mary , 11 South Rd , 282 1324) (Peter , 9 Port Rd , 678 9862)
9.7. a tha k
Cc lp dn xut m chng ta bt gp n thi im ny trong chng ny ch l biu din n tha k, bi v mi lp tha k cc thuc tnh ca n t mt lp c s n. Mt tip cn c th khc, mt lp dn xut c th c nhiu lp c s. iu ny c bit n nh l a tha k (multiple inheritance). V d, chng ta phi nh ngha hai lp tng ng biu din cc danh sch ca cc ty chn v cc ca s im nh:
class OptionList { public: OptionList (int n); ~OptionList (void); //... }; class Window { public: Window (Rect &bounds); ~Window (void); //... };
Chng 9: Tha k
159
Mt menu l mt danh sch ca cc ty chn c hin th bn trong ca s ca n. V th n c th nh ngha Menu bng cch dn xut t lp OptionList v lp Window:
class Menu : public OptionList, public Window { public: Menu (int n, Rect &bounds); ~Menu (void); //... };
Vi a tha k, mt lp dn xut tha k tt c cc thnh vin ca cc lp c s ca n. Nh trc, mi thnh vin ca lp c s c th l ring, chung, hay l c bo v. p dng cng cc nguyn l truy xut thnh vin lp c s. Hnh 9.4 minh ha th bc lp cho Menu..
Hnh 9.4 Th bc lp cho Menu
OptionLis t Window
Menu
V cc lp c s ca lp Menu c cc hm xy dng yu cu cc i s nn hm xy dng cho lp dn xut nn triu gi nhng hm xy dng trong danh sch khi to thnh vin ca n:
Menu::Menu (int n, Rect &bounds) : OptionList(n), Window(bounds) { //... }
Th t m cc hm xy dng c triu gi cng vi th t m chng c c t trong phn u ca lp dn xut (khng theo th t m chng xut hin trong danh sch khi to thnh vin ca cc hm xy dng lp dn xut). V d, vi Menu hm xy dng cho lp OptionList c triu gi trc khi hm xy dng cho lp Window, thm ch nu chng ta chuyn i th t trong hm xy dng:
Menu::Menu (int n, Rect &bounds) : Window(bounds), OptionList(n) { //... }
Chng 9: Tha k
160
S ci t r rng ca i tng lp dn xut l cha ng mt i tng t mi i tng ca cc lp c s ca n. Hnh 9.5 minh ha mi quan h gia mt i tng lp Menu v cc i tng lp c s.
Hnh 9.5 Cc i tng lp dn xut v c s.
OptionList object OptionList data members Window object
Window data members Menu object OptionList data members
9.8. S m h
a tha k lm phc tp thm na cc qui lut tham kho ti cc thnh vin ca mt lp. V d, gi s c hai lp OptionList v Window c mt hm thnh vin gi l Highlight lm ni bc mt phn c th ca kiu i tng ny hay kiu kia:
class OptionList { public: //... void Highlight (int part); }; class Window { public: //... void Highlight (int part); };
(trong m l mt i tng Menu) l m h v s khng bin dch bi v n khng r rng, n tham kho ti hoc l OptionList::Highlight hoc l Window::Highlight. S m h c gii quyt bng cch lm cho li gi r rng:
Chng 9: Tha k
161
m.Window::Highlight(0);
Mt kh nng chn la khc, chng ta c th nh ngha mt hm thnh vin Highlight cho lp Menu gi cc thnh vin Highlight ca cc lp c s:
class Menu : public OptionList, public Window { public: //... void Highlight (int part); }; void Menu::Highlight (int part) { OptionList::Highlight(part); Window::Highlight(part); }
Nhng chuyn i nh th l an ton bi v i tng lp dn xut lun cha ng tt c cc i tng lp c s ca n. V d, php gn u tin lm cho thnh phn Window ca menu c gn ti win. Ngc li, khng c s chuyn i t lp c s thnh lp dn xut. L do mt s chuyn kiu nh th c kh nng nguy him v thc t i tng lp dn xut c th c cc d liu thnh vin khng c mt trong i tng lp c s. V th cc thnh vin d liu ph kt thc bi cc gi tr khng th tin ton. Tt c chuyn kiu nh th phi c p kiu r rng xc nhn nh ca lp trnh vin:
Menu Menu &mRef = (Menu&) win; *mPtr = (Menu*) &win; // cn thn! // cn thn!
Mt i tng lp c s khng th c gn ti mt i tng lp c s tr phi c mt hm xy dng chuyn kiu trong lp dn xut c nh ngha cho mc ch ny. V d, vi
class Menu : public OptionList, public Window { public: //... Menu (Window&); };
Chng 9: Tha k
162
th cu lnh gn sau l hp l v c th s dng hm xy dng chuyn i win thnh i tng Menu trc khi gn:
menu = win; // triu gi Menu::Menu(Window&)
9.10.Lp c s o
Tr li lp Menu v gi s rng hai lp c s ca n cng c dn xut t nhiu lp khc:
class OptionList : public Widget, List { /*...*/ }; class Window : public Widget, Port { /*...*/ }; class Menu : public OptionList, public Window { /*...*/ };
V lp Widget l lp c s cho c hai lp OptionList v Window nn mi i tng menu s c hai i tng widget (xem Hnh 9.6a). iu ny l khng mong mun (bi v mt menu c xem xt l mt widget n) v c th dn n m h. V d, khi p dng hm thnh vin widget ti mt i tng menu, tht khng r rng nh p dng ti mt trong hai i tng widget. Vn ny c khc phc bng cch lm cho lp Widget l mt lp c s o ca lp OptionList v Window. Mt lp c s c lm cho o bng cch t t kha virtual trc tn ca n trong phn u lp dn xut:
class OptionList : virtual public Widget, List class Window : virtual public Widget, Port { /*...*/ }; { /*...*/ };
iu ny m bo rng mt i tng Menu s cha ng va ng mt i tng Widget. Ni cch khc, lp OptionList v lp Window s chia s cng i tng Widget. Mt i tng ca mt lp m c dn xut t mt lp c s o khng cha ng trc tip i tng ca lp c s o m ch l mt con tr ti n (xem Hnh 9.6b v 9.6c). iu ny cho php nhiu hnh vi ca mt lp o trong mt h thng cp bc c ghp li thnh mt (xem Hnh 9.6d). Nu trong mt h thng cp bc lp mt vi th hin ca lp c s X c khai bo nh l o v cc th hin khc nh l khng o th sau i tng lp dn xut s cha ng mt i tng X cho mi th hin khng o ca X, v mt i tng n X cho tt c s xy ra o ca X. Mt i tng lp c s o khng c khi to bi lp dn xut trc tip ca n m c khi to bi lp dn xut xa nht di h thng cp bc lp. Lut ny m bo rng i tng lp c s o c khi to ch mt ln. V d, trong mt i tng menu, i tng widget c khi to bi hm
Chng 9: Tha k
163
Khng quan tm v tr n xut hin trong mt h thng cp bc lp, mt i tng lp c s o lun c xy dng trc cc i tng khng o trong cng h thng cp bc.
Hnh 9.6 Cc lp c s o v khng o
(a) Menu object
Widget data members List data members OptionList data members
(c) Window object with Widget as virtual
Nu trong mt h thng cp bc lp mt c s o c khai bo vi cc phm vi truy xut i lp (ngha l, bt k s kt hp ca ring, c bo v, v chung) sau kh nng truy xut ln nht s thng tr. V d, nu Widget c khai bo l mt lp c s o ring ca lp OptionList v l mt lp c s o chung ca lp Window th sau n s vn cn l mt lp c s o chung ca lp Menu.
Chng 9: Tha k
164
Tng t, php gn memberwise c iu khin bi ti nh ngha ton t = c pht ra t ng (hay do ngi dng nh ngha):
Y& Y::operator = (Y&)
Khi to memberwise (hoc gn) ca i tng lp dn xut lin quan n khi to memberwise (hoc gn) ca cc lp c s ca n cng nh l cc thnh vin i tng lp ca n. Cn s quan tm c bit khi mt lp dn xut nh vo ti nh ngha cc ton t new v delete cho lp c s ca n. V d, tr li vic ti nh ngha hai ton t ny cho lp Point trong Chng 7, v gi s rng chng ta mun s dng chng cho mt lp dn xut:
class Point3D : public Point { public: //... private: int depth; };
Bi v s ci t ca Point::operator new gi s rng khi c cn s c kch thc ca i tng Point, vic tha k ca n bi lp Point3D dn ti mt vn : khng th gii thch ti sao d liu thnh vin ca lp Point3D (ngha l, depth) li cn khng gian ph. trnh vn ny, ti nh ngha ca ton t new c gng cp pht va ng tng s lng lu tr c ch nh bi tham s kch thc ca n hn l mt kch thc gii hn trc. Tng t, ti nh ngha ca delete nn ch vo kch c c ch nh bi tham s th hai ca n v c gng gii phng va ng cc byte ny.
Chng 9: Tha k
165
Bi tp cui chng 9
9.1 Xem xt lp Year chia cc ngy trong nm thnh cc ngy lm vic v cc ngy ngh. Bi v mi ngy c mt gi tr nh phn nn lp Year d dng c dn xut t BitVec:
enum Month { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec }; class Year : public BitVec { public: Year (const short year); void WorkDay (const short day);// dat ngay nhu ngay lam viec void OffDay (const short day);// dat ngay nhu ngay nghi Bool Working (const short day);// true neu la ngay lam viec short Day (const short day, // chuyen date thanh day const Month month, const short year); protected: short year; // nam theo lich };
Cc ngy c nh s t im bt u ca nm, bt u t ngy 1 thng 1 nm 1. Hon tt lp Year bng cch thi cng cc hm thnh vin ca n. 9.2 Cc bng lit k c gii thiu bi mt khai bo enum l mt tp con nh ca cc s nguyn. Trong mt vi ng dng chng ta c th cn xy dng cc tp hp ca cc bng lit k nh th. V d, trong mt b phn tch c php, mi hm phn tch c th c truyn mt tp cc k hiu m s c b qua khi b phn tch c php c gng phc hi t mt li h thng. Cc k hiu ny thng thng c dnh ring nhng t ca ngn ng:
enum Reserved {classSym, privateSym, publicSym, protectedSym, friendSym, ifSym, elseSym, switchSym,...};
Vi nhng th cho c th c nhiu nht n phn t (n l mt s nh) tp hp c th c trnh by c hiu qu nh mt vect bit ca n phn t. Dn xut mt lp t tn l EnumSet t BitVec lm cho iu ny d dng. Lp EnumSet nn ti nh ngha cc ton t sau: Ton t + hp tp hp. Ton t - hiu tp hp. Ton t * giao tp hp. Ton t % kim tra mt phn t c l thnh vin ca tp hp. Cc ton t <= v >= kim tra mt tp hp c l mt tp con ca tp khc hay khng. Cc ton t >> v << thm mt phn t ti tp hp v xa mt phn t t tp hp. 9.3 Lp tru tng l mt lp m khng bao gi c s dng trc tip nhng cung cp mt khung cho cc lp khc c dn xut t n. Thng thng, tt
166
Chng 9: Tha k
N cung cp mt khung cho cc lp ging nh c s d liu. Cc v d ca loi lp c th c dn xut t c s d liu gm: danh sch lin kt, cy nh phn, v B-cy. Trc tin dn xut lp B-cy t lp Database v sau dn xut lp B*-cy t lp B-cy:
class BTree : public Database { /*...*/ }; class BStar : public BTree { /*...*/ };
Chng 9: Tha k
167