Toántửgáncủalớpdẫnxuất 7.1. Khi nào cần xây dựng toántử gán: Khi lớpdẫnxuất có các thuộc tính (kể cả thuộc tính thừa kế từ các lớp cơ sở) là con trỏ, thì nhất thiết không được dùng toántửgán mặc định, mà phải xây dựng cho lớpdẫnxuất một toántử gán. 7.2. Cách xây dựng toántửgán cho lớpdẫnxuất + Trước hết cần xây dựng toán tửgán cho các lớp cơ sở + Vấn đề mấu chốt là: Khi xây dựng toán tửgán cho lớpdẫnxuất thì làm thế nào để sử dụng được các toántửgán của lớp cơ sở. Cách giải quyết như sau: - Xây dựng các phương thức (trong các lớp cơ sở) để nhận được địa chỉ của đối tượng ẩn của lớp. Phương thức này được viết đơn giản theo mẫu: Tên_lớp * get_DT ( ) { return this ; } - Trong thân củatoántửgán (cho lớpdẫn xuất), sẽ dùng phương thức trên để nhận địa chỉ đối tượng củalớp cơ sở mà lớpdẫnxuất thừa kế. Sau đó thực hiện phép gán trên các đối tượng này. Phương pháp nêu trên có thể minh hoạ một cách hình thức như sau: Giả sử lớp B dânxuấttừ A. Để xây dựng toán tửgán cho B, thì: 1. Trong lớp A cần xây dựng toántửgán và phương thức cho địa chỉ của đối tượng ẩn. Cụ thể A cần được định nghĩa như sau: class A { . A & operator=(A& h) { //các câu lệnh để thực hiện gán trong A } // Phương thức nhận địa chỉ đối tượng ẩn của A A* get_A() { return this; } . } ; 2. Toántửgán trong lớp B cần như sau: class B : public A { . B & operator=(B& h) { A *u1, *u2; u1 = this->get_A(); u2 = h.get_A(); *u1 = *u2 ; // Sử dụng phép gán trong A để gán các // thuộc tính mà B kế thừa từ A //Các câu lệnh thực hiện gán các thuộc tính riêng của B } . } ; 7.3. Ví dụ Chương trình dưới đây minh hoạ cách xây dựng toán tửgán cho lớp D có 2 lớp cơ sở là C và B (C là lớp cơ sở trực tiếp, còn B là cơ sở của C) . Ngoài ra D còn có một thuộc tính là đối tượng củalớp A. //CT5-08 // Thua ke nhieu muc // gan #include <conio.h> #include <stdio.h> #include <iostream.h> #include <string.h> class A { private: int a; char *str ; public: A() { a=0; str=NULL; } A& operator=(A& h) { this->a = h.a; if (this->str!=NULL) delete this->str; this->str = strdup(h.str); return h; 271 272 } void nhap() { cout << "\nNhap so nguyen lop A: " ; cin >> a ; if (str!=NULL) delete str; cout << "\nNhap chuoi lop A: " ; char tg[30]; fflush(stdin); gets(tg); str = strdup(tg); } void xuat() { cout << "\n" << "So nguyen lop A= " << a << " Chuoi lop A: " << str ; } } ; class B { private: int b; char *str ; public: B() { b=0; str=NULL; } B* getB() { return this; } B& operator=(B& h) { this->b = h.b; if (this->str!=NULL) delete this->str; this->str = strdup(h.str); return h; } void nhap() { 273 274 cout << "\nNhap so nguyen lop B: " ; cin >> b ; if (str!=NULL) delete str; cout << "\nNhap chuoi lop B: " ; char tg[30]; fflush(stdin); gets(tg); str = strdup(tg); } void xuat() { cout << "\n" << "So nguyen lop B = " << b << " Chuoi lop B: " << str ; } } ; class C : public B { private: int c; char *str ; public: C():B() { c=0; str=NULL; } C* getC() { return this; } C& operator=(C& h) { B *b1, *b2; b1= this->getB(); b2= h.getB(); *b1 = *b2; this->c = h.c; if (this->str!=NULL) delete this->str; this->str = strdup(h.str); return h; } void nhap() 275 276 { B::nhap(); cout << "\nNhap so nguyen lop C: " ; cin >> c ; if (str!=NULL) delete str; cout << "\nNhap chuoi lop C: " ; char tg[30]; fflush(stdin); gets(tg); str = strdup(tg); } void xuat() { B::xuat(); cout << "\n" << "So nguyen lop C = " << c << " Chuoi lop C: " << str ; } } ; class D : public C { private: int d; char *str ; A u; public: D():C(),u() { d=0; str=NULL; } D& operator=(D& h) { this->u = h.u; C *c1,*c2; c1 = this->getC(); c2 = h.getC(); *c1 = *c2; this->d = h.d; if (this->str!=NULL) delete this->str; this->str = strdup(h.str); return h; } void nhap() { u.nhap(); C::nhap(); cout << "\nNhap so nguyen lop D: " ; cin >> d ; if (str!=NULL) delete str; cout << "\nNhap chuoi lop D: " ; char tg[30]; fflush(stdin); gets(tg); str = strdup(tg); } void xuat() { u.xuat(); C::xuat(); cout << "\n" << "So nguyen lop D = " << d << " Chuoi lop D: " << str ; } } ; void main() { D h1,h2,h3; clrscr(); h1.nhap(); h3=h2=h1; cout<<"\n\nH2:"; h2.xuat(); cout<<"\n\nH3:"; h3.xuat(); h1.nhap(); cout<<"\n\nH2:"; h2.xuat(); cout<<"\n\nH3:"; h3.xuat(); cout<<"\n\nH1:"; h1.xuat(); getch(); } 277 278 . dùng toán tử gán mặc định, mà phải xây dựng cho lớp dẫn xuất một toán tử gán. 7.2. Cách xây dựng toán tử gán cho lớp dẫn xuất + Trước hết cần xây dựng toán. Toán tử gán của lớp dẫn xuất 7.1. Khi nào cần xây dựng toán tử gán: Khi lớp dẫn xuất có các thuộc tính (kể cả thuộc tính thừa kế từ các lớp cơ sở)