Chuong - 09 - Thua Ke

You might also like

You are on page 1of 20

Chng 9.

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; }

Hm main sau thc thi lp ContactDir bng cch to ra mt th mc nh v gi cc hm thnh vin:


int main (void) { ContactDir 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; cout << "Find Jane: " << *dir.Find("Jane") << '\n'; dir.Delete("Jack");

Chng 9: Tha k

151

};

cout << "Deleted Jack\n"; cout << dir; return 0;

Khi chy n s cho kt qu sau:


(Mary , 11 South Rd , 282 1324) (Peter , 9 Port Rd , 678 9862) (Jane , 321 Yara Ln , 982 6252) (Jack , 42 Wayne St , 663 2989) (Fred , 2 High St , 458 2324) Find Jane: (Jane , 321 Yara Ln , 982 6252) Deleted Jack (Mary , 11 South Rd , 282 1324) (Peter , 9 Port Rd , 678 9862) (Jane , 321 Yara Ln , 982 6252) (Fred , 2 High St , 458 2324)

9.2. Lp dn xut n gin


Chng ta mun nh ngha mt lp gi l SmartDir ng x ging nh l lp ContactDir v theo di tn ca i tc mi va c tm kim gn nht. Lp SmartDir c nh ngha tt nht nh l mt dn xut ca lp ContactDir nh c minh ha bi Danh sch 9.2.
Danh sch 9.2 1 class SmartDir : public ContactDir { 2 public: 3 SmartDir(const int max) : ContactDir(max) {recent = 0;} 4 Contact* Recent (void); 5 Contact* Find (const char *name); 6 private: 7 char 8 }; Ch gii * recent; // ten duoc tim gan nhat

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

Cc hm thnh vin c nh ngha nh sau:


Contact* SmartDir::Recent (void) { return recent == 0 ? 0 : ContactDir::Find(recent); } Contact* SmartDir::Find (const char *name) { Contact *c = ContactDir::Find(name); if (c != 0) recent = (char*) c->Name(); return c; }

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

SmartDir. Hnh 9.1 minh ha vic to ra mt i tng ContactDir v mt i tng SmartDir.


Hnh 9.1 Cc i tng lp c s v lp dn xut.
ContactDir object contacts dirSize maxSize SmartDir object contacts dirSize maxSize recent

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

Th t xy dng v hy b i tng ca lp dn xut.


c being constructed c being destroyed

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... };

9.5. Lp c s ring, chung, v c bo v


Mt lp c s c th c ch nh l ring, chung, hay c bo v. Nu khng c ch nh nh th, lp c s c gi s l ring:
class A { private: int x; void Fx (void); public: int y; void Fy (void); protected: int z; void Fz (void); }; class B : A {}; // A la lop co so rieng cua B class C : private A {}; // A la lop co so rieng cua C class D : public A {}; // A la lop co so chung cua D class E : protected A {}; // A la lop co so duoc bao ve cua E

C x ca nhng lp ny l nh sau (xem Bng 9.1 cho mt tng kt):

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

Cc qui lut tha k truy xut lp c s.


Lp c s Private Member Public Member Protected Member Dn xut ring private private private Dn xut chung private public protected Dn xut c bo v private protected protected

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 //... };

Lookup (const char *name);

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) { //... }

Cc hm hy c ng dng theo th t ngc li: ~Menu, k l ~Window, v cui cng l ~OptionList.

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

Window data members Menu data members

Thng thng, mt lp dn xut c th c s lng cc lp c s bt k, tt c chng phi phn bit:


class X : A, B, A { //... }; // khng hp qui tc: xut hin hai ln

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); };

Lp dn xut Menu s tha k c hai hm ny. Kt qu l, li gi


m.Highlight(0);

(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); }

9.9. Chuyn kiu


i vi bt k lp dn xut no c mt s chuyn kiu khng tng minh t lp dn xut ti bt k lp c s chung ca n. iu ny c th c s dng chuyn mt i tng lp dn xut thnh mt i tng lp c s nh l mt i tng thch hp, mt tham chiu, hoc mt con tr:
Menu menu(n, bounds); Window win = menu; Window &wRef = menu; Window *wPtr = &menu;

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

xy dng Menu (ghi li gi hm ca hm xy dng Widget bi OptionList hoc Window):


Menu::Menu (int n, Rect &bounds) : { //... } Widget(bounds), OptionList(n), Window(bounds)

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

(b) OptionList object with Widget as virtual


Widget data members List data members OptionList data members

Widget data members


Port data members

Widget data members Window data members

Port data members Window data members Menu data members


(d) Menu object with Widget as virtual
List data members OptionList data members Widget data members

Port data members Window data members

Menu data members

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

9.11.Cc ton t c ti nh ngha


Ngoi tr ton t gn, mt lp dn xut tha k tt c cc ton t ti nh ngha ca lp c s ca n. Ton t c ti nh ngha bi chnh lp dn xut che giu i vic ti nh ngha ca cng ton t bi cc lp c s (ging nh l cc hm thnh vin ca mt lp dn xut che giu i cc hm thnh vin ca cc lp c s). Php gn v khi to memberwise (xem Chng 7) m rng ti lp dn xut. i vi bt k lp Y dn xut t X, khi to memberwise c iu khin bi mt hm xy dng pht ra t ng (hay do ngi dng nh ngha) hnh thc:
Y::Y (const Y&);

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

c cc hm thnh vin ca mt lp tru tng l o. Bn di l mt v d n gin ca mt lp tru tng:


class Database { public: virtual void Insert(Key, Data) {} virtual void Delete (Key) {} virtual Data Search (Key) {return 0;} };

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 { /*...*/ };

Trong bi tp ny s dng kiu c sn int cho Key v double cho Data.

Chng 9: Tha k

167

You might also like