Lập trình hướng đối tượng với C++ - Phụ lục 3: Bài toán quan hệ gia đình
Trong mục này, ta sẽ xây dựng chương trình cho bài toán quan hệ gia đình đã được phân tích ở chương một. Theo như sự phân tích ban đầu của bài toán, ta có một tập các cá thể và mô tả bằng lớp Con người bao gồm các thuộc tính tên, anh em, cha mẹ, . và các phương thức sinh, cưới, . Nhưng ta có nhận xét rằng phương thức sinh chỉ thực hiện được trên những cá thể là nữ và phương thức cưới chỉ xảy ra cho hai cá thể khác giới. Như vậy có sự phân chia tập đối tượng của bài toán thành hai lớp khác nhau là Nam và Nữ. Rõ ràng, hai lớp này phải kế thừa từ lớp Con người. Lớp con người sẽ chứa các thuộc tính và phương thức chung, dù cá thể là Nam hay Nữ cũng đều phải có. Ngoài cá thành phần được kế thừa từ lớp Con người, lớp Nam có thêm thuộc tính Vợ, lớp Nữ có thêm thuộc tính Chồng và phương thức Sinh con.
(Nguoi *); virtual int LaVo(Nguoi*)=0; virtual int LaChong(Nguoi*)=0; }; class Nam : public Nguoi { Nu *Vo; int LaVo(Nguoi *) { return 0; } public: Nam(char *ten, Nam *bo=0, Nu *me=0) : Nguoi(ten, bo, me), Vo(0) {} int GioiTinh() { return 1; } int Cuoi(Nguoi *vo); int LaChong(Nguoi * nguoi); }; class Nu : public Nguoi { Nam *Chong; int LaChong(Nguoi *) { return 0; } public: Nu(char *ten, Nam *bo=0, Nu *me=0): Nguoi(ten, bo, me), Chong(0) {} int GioiTinh() { return 0; } int Cuoi(Nguoi *chong); void SinhCon(char* ten, int gioitinh); int LaVo(Nguoi * nguoi); }; Ph¬ng thøc cíi chØ thùc hiÖn ®èi víi c¸ thÓ cha lËp gia ®×nh. Trong trêng hîp ®· lËp gia ®×nh th× nã sÏ tr¶ ra 0. int Nam::Cuoi(Nguoi *vo) { if (Vo||vo->GioiTinh()) return 0; Vo = (Nu*)vo; Vo->Cuoi(this); return 1; } int Nu::Cuoi(Nguoi *chong) { if (Chong||chong->GioiTinh()==0) return 0; Chong = (Nam*)chong; Chong->Cuoi(this); return 1; } void Nu::SinhCon(char *ten, int gioitinh) { Nguoi* nguoi = TaoNguoi(ten, gioitinh, Chong, this); ThemCon(nguoi); if (Chong) Chong->ThemCon(nguoi); for (int i=0; i<SoCon; i++) { CacCon[i]->ThemEm(nguoi); nguoi->ThemAnhChi(CacCon[i]); } } Trong ph¬ng thøc sinh con ®· dïng hµm TaoNguoi ®Ó t¹o ra mét thÓ hiÖn cña líp Nam hay Nu phô thuéc vµo giíi tÝnh. §èi tîng míi t¹o ra sÏ ®îc gia nhËp vµo céng ®ång vµ ®îc xem xÐt c¸c mèi quan hÖ sau nµy, chi tiÕt vÒ hµm nµy chóng ta sÏ bµn luËn sau. Sau khi ®· cã ®èi tîng th× c¸c mèi quan hÖ gia ®×nh cha, mÑ, con c¸i, anh, chÞ, em ph¶i ®îc x¸c lËp. Thùc hiÖn cµi ®Æt c¸c ph¬ng thøc tr¶ lêi c©u hái quan hÖ cña líp Con ngêi. §èi víi c¸c mèi quan hÖ gÇn nh LaAnh, LaCha th× viÖc kiÓm tra rÊt ®¬n gi¶n th«ng qua c¸c thuéc tÝnh Bo, Me, AnhChi,... cña ®èi tîng. Nhng ®èi víi mèi quan hÖ xa h¬n chót Ýt nh LaOngNoi, LaCo, LaChu,... th× trë nªn khã kh¨n h¬n nhiÒu. Chóng ta dïng mét ph¬ng ph¸p kiÓm tra ®¬n gi¶n theo m« h×nh to¸n häc. VÝ dô, A lµ «ng néi cña B khi vµ chØ khi trong céng ®ång tån t¹i mét ®èi tîng X mµ A lµ cha cña X vµ X lµ cha cña B. Nh vËy ®Ó thùc hiÖn ®îc kiÓm tra nµy th× cÇn ph¶i lu ®îc toµn bé c¸c ®èi tîng trong céng ®ång ®Ó phôc vô t×m kiÕm X. Trong ch¬ng tr×nh dïng mét m¶ng tÜnh c¸c con trá tíi ®èi tîng Con ngêi ®Ó qu¶n lý céng ®ång ngêi nµy. M¶ng nµy ®îc khai b¸o nh mét thµnh phÇn tÜnh cña líp Con ngêi. Ph¬ng thøc TaoNguoi sÏ t¹o mét ®èi tîng lµ Nam hoÆc N÷ phô thuéc giíi tÝnh truyÒn vµo. §èi tîng míi t¹o ra sÏ ®îc thªm vµo céng ®ång. Ph¬ng thøc TimNguoi t×m ®èi tîng trong céng ®ång cã tªn nh tªn ®a vµo, nÕu kh«ng t×m thÊy tr¶ vÒ NULL. Díi ®©y lµ mét sè bæ sung cho líp Con ngêi. class Nguoi { . . . static Nguoi* NhanDan[100]; static int SoDan; public: . . . static int LaySoDan() { return SoDan; } static Nguoi* ThemDan(Nguoi* nguoi) { return NhanDan[SoDan++] = nguoi; } static Nguoi* TaoNguoi(char*, int, Nam *bo=0, Nu *me=0); static Nguoi* TimNguoi(char* ten); }; Nguoi* Nguoi::NhanDan[]; int Nguoi::SoDan = 0; Nguoi* Nguoi::TaoNguoi(char* ten, int gioitinh, Nam *bo, Nu *me) { return gioitinh ? ThemDan(new Nam(ten, bo, me)) : ThemDan(new Nu(ten, bo, me)); } Nguoi* Nguoi::TimNguoi(char* ten) { for (int i=0; i<SoDan; i++) if (strcmp(ten, NhanDan[i]->LayTen())==0) return NhanDan[i]; return 0; } Sau khi ®· tæ chøc ®îc d÷ liÖu lu tr÷ con ngêi chóng ta cã thÓ x©y dùng c¸c hµm kiÓm tra quan hÖ nh díi ®©y. A lµ ®èi tîng gäi hµm kiÓm tra, B lµ ®èi tîng truyÒn vµo, X lµ ®èi tîng t×m kiÕm NhanDan[i] (dïng vßng for ®Ó duyÖt). int Nguoi::LaOngNoi(Nguoi *nguoi) { if (GioiTinh()==0) return 0; for (int i=0; i<SoDan; i++) if (LaCha(NhanDan[i])&&NhanDan[i]->LaCha(nguoi)) return 1; return 0; } int Nguoi::LaBaNoi(Nguoi *nguoi) { if (GioiTinh()) return 0; for (int i=0; i<SoDan; i++) if (LaMe(NhanDan[i])&&NhanDan[i]->LaCha(nguoi)) return 1; return 0; } Môc ®Ých cña ch¬ng tr×nh lµ sau khi ®· cã d÷ liÖu ph¶i tr¶ lêi ®îc c©u hái quan hÖ khi ®a tªn hai ngêi vµo. Sau khi ngêi sö dông ®a tªn vµo chóng ta sÏ t×m ®èi tîng ®ã trong céng ®ång. NÕu t×m thÊy th× gäi hµm ®a ra th«ng b¸o quan hÖ cña hai ®èi tîng võa t×m thÊy. Trong hµm díi ®©y thùc hiÖn b»ng c¸ch kiÓm tra c¸c quan hÖ bÒ trªn nÕu tÊt c¶ kh«ng tho¶ m·n th× l¹i ®æi ngîc l¹i ®èi tîng gäi ph¬ng thøc ®Ó kiÓm tra. char qh[256]; // ®a ra th«ng b¸o vÒ quan hÖ cña 2 ®èi tîng char* QuanHe(Nguoi* A, Nguoi* B) { for (int i=1; i<=2; i++) { strcpy(qh, A->LayTen()); strcat(qh, " va "); strcat(qh, B->LayTen()); strcat(qh, " co quan he "); if (A->LaOngNoi(B)) return strcat(qh, "ong chau noi"); if (A->LaBaNoi(B)) return strcat(qh, "ba chau noi"); if (A->LaOngNgoai(B)) return strcat(qh, "ong chau ngoai"); if (A->LaBaNgoai(B)) return strcat(qh, "ba chau ngoai"); if (A->LaCha(B)) return strcat(qh, "cha con"); if (A->LaMe(B)) return strcat(qh, "me con"); if (A->LaCo(B)) return strcat(qh, "co chau"); if (A->LaDi(B)) return strcat(qh, "di chau"); if (A->LaChu(B)) return strcat(qh, "chu chau"); if (A->LaBac(B)) return strcat(qh, "bac chau"); if (A->LaAnh(B)) return strcat(qh, "anh em"); if (A->LaChi(B)) return strcat(qh, "chi em"); if (A->LaAnhHo(B)) return strcat(qh, "anh em ho"); if (A->LaChiHo(B)) return strcat(qh, "chi em ho"); if (A->LaVo(B)) return strcat(qh, "vo chong"); Nguoi* temp = A; A = B; B = temp; } strcpy(qh, A->LayTen()); strcat(qh, " va "); strcat(qh, B->LayTen()); return strcat(qh, " khong co quan he gia dinh"); } // t×m quan hÑ cña hai ®èi tîng cã tªn nhËp vµo tõ bµn phÝm void TimQuanHe() { clrscr(); char ten1[25]; cout << "Ten nguoi thu nhat: "; gets(ten1); Nguoi *A = Nguoi::TimNguoi(ten1); if (A==0) { cout << "Khong co nguoi ten " << ten1 << endl; getch(); return; } char ten2[25]; cout << "Ten nguoi thu hai: "; gets(ten2); Nguoi *B = Nguoi::TimNguoi(ten2); if (B==0) { cout << "Khong co nguoi ten " << ten2 << endl; getch(); return; } cout << QuanHe(A, B) << endl; getch(); } §Ó ®¬n gi¶n trong viÖc thiÕt kÕ nhËp d÷ liÖu cho ch¬ng tr×nh, chóng ta dïng ph¬ng ph¸p nhËp d÷ liÖu tõ tÖp. ViÖc h×nh thµnh con ngêi vµ c¸c mèi quan hÖ cña chóng lµ th«ng qua c¸c sù kiÖn chÝnh: T¹o mét con ngêi, §¸m cíi cña hai ngêi, Sinh con cña ngêi phô n÷. Do vËy tÖp d÷ liÖu ph¶i thÓ hiÖn ®îc ®iÒu nµy. Dïng tÖp v¨n b¶n ®Ó m« t¶ c¸c sù kiÖn tá ra thÝch hîp trong trêng hîp nµy. Díi ®©y lµ mét tÖp v¨n b¶n m« t¶ cho mét quan hÖ gia ®×nh ®¬n gi¶n. Th¾ng (Nam) Mai (N÷) Nga (N÷) TuÊn (Nam) TÖp v¨n b¶n d÷ liÖu: Tao Thang 1 Tao Mai 0 Cuoi Thang Mai Sinh Mai Nga 0 Sinh Mai Tuan 1 T¹o ngêi tªn Th¾ng lµ nam T¹o ngêi tªn Mai lµ n÷ Th¾ng cíi Mai Mai sinh con g¸i tªn lµ Nga Mai sinh con trai tªn lµ TuÊn Hµm nhËp d÷ liÖu tõ tÖp v¨n b¶n. void NhapDuLieu() { clrscr(); char s[80]; cout << "Ten tep nhap du lieu: "; cin >> s; ifstream input(s, ios::in|ios::nocreate); input.seekg(0L, ios::end ); if ( input.tellg() < 0) { cout << "Loi mo tep ! \n"; getch(); return; } input.seekg(0L, ios::beg); cout << "Dang nhap du lieu........\n"; int dong = 1; while (1) { input.getline(s, sizeof(s)); if (input.gcount()==0) break; if (strcmp(s, "")==0) { dong++; continue; } if (strcmp(s, "Tao")==0) { char ten[25]; input.getline(ten, sizeof(ten)); if (strcmp(ten, "")) { int gt; input >> gt; cout << "Tao nguoi ten " << ten << endl; if (Nguoi::TimNguoi(ten)) cout << "Da co nguoi ten la " << ten << endl; else Nguoi::TaoNguoi(ten, gt); dong += 2; continue; } } if (strcmp(s, "Cuoi")==0) { char ten1[25]; input.getline(ten1, sizeof(ten1)); char ten2[25]; input.getline(ten2, sizeof(ten2)); Nguoi* A = Nguoi::TimNguoi(ten1); Nguoi* B = Nguoi::TimNguoi(ten2); cout << "Cuoi " << ten1 << " va "<< ten2 << endl; if (A==0) cout << "Khong co nguoi ten " << ten1 << endl; if (B==0) cout << "Khong co nguoi ten " << ten2 << endl; if (A&&B&&A->Cuoi(B)==0) cout << "Khong cuoi duoc\n"; dong += 2; continue; } if (strcmp(s, "Sinh")==0) { char ten1[25]; input.getline(ten1, sizeof(ten1)); char ten2[25]; input.getline(ten2, sizeof(ten2)); if (strcmp(ten2, "")) { cout << ten1 << " sinh con "<< ten2 << endl; Nguoi* A = Nguoi::TimNguoi(ten1); if (A==0) cout << "Khong co nguoi ten " << ten1 << endl; int gt; input >> gt; if (Nguoi::TimNguoi(ten2)) cout << "Da co nguoi ten la " << ten2 << endl; else { if ( A ) if ( A->GioiTinh() ) cout << ten1 <<" la nam khong sinh con duoc\n"; else ((Nu*)A)->SinhCon(ten2, gt); } dong += 3; continue; } } cout << "Loi o dong thu " << dong << endl; break; } cout << "Ket thuc nhap.\n"; getch(); } ViÕt thªm menu cho ch¬ng tr×nh cã d¹ng nh sau: Lua chon cong viec theo so 1. Nhap du lieu 2. Tim quan he 3. Ket thuc void Menu() { clrscr(); cout << "\n\n Lua chon cong viec theo so\n\n"; cout << " 1. Nhap du lieu\n"; cout << " 2. Tim quan he\n"; cout << " 3. Ket thuc\n"; } void main(){ int i; Menu(); do { i = getch(); switch (i) { case '1': Nguoi::XoaDuLieu(); NhapDuLieu(); Menu(); break; case '2': TimQuanHe(); Menu(); } }while (i!='3'); Nguoi::XoaDuLieu(); } VÝ dô sau khi nhËp d÷ liÖu cho ch¬ng tr×nh tõ tÖp d÷ liÖu nh ta cã ë trªn vµ thùc hiÖn t×m quan hÖ mµn h×nh sÏ cã d¹ng nh sau Ten nguoi thu nhat: Thang Ten nguoi thu hai: Mai Mai va Thang co quan he vo chong
File đính kèm:
- Lập trình hướng đối tượng với C++ - Phụ lục 3 Bài toán quan hệ gia đình.DOC