Hàmtạosaochépcủalớpdẫnxuất 8.1. Khi nào cần xây dựng hàmtạosao chép: 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 hàmtạosaochép mặc định, mà phải xây dựng cho lớpdẫnxuất một hàmtạosao chép. 8.2. Cách xây dựng hàmtạosaochép cho lớpdẫnxuất + Trước hết cần xây dựng toán tử gán cho lớpdẫnxuất (xem § 7). + Sau đó xây dựng hàmtạosaochép cho lớpdẫnxuất theo mẫu: Tên_lớp_dẫn_xuất (Tên_lớp_dẫn_xuất &h ) { *this = h ; } 8.3. Ví dụ Chương trình dưới đây minh hoạ cách xây dựng hàmtạosaochép 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. Chương trình này dựa trên chương trình trong mục 7.3 với 2 thay đổi: + Xây dựng thêm hàmtạosaochép cho lớp D. + Thay đổi một số câu lệnh trong hàm main để sử dùng hàmtạosao chép. Để thấy rõ vai trò củahàmtạosaochép chúng ta hãy so sánh kết quả nhận được trong 2 trường hợp: Có hàmtạosaochép và bỏ đi hàm này. //CT5-09 // Thua ke nhieu muc // Hamtaosaochep #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) { 279 280 this->a = h.a; if (this->str!=NULL) delete this->str; this->str = strdup(h.str); return h; } 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() { 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; 281 282 this->str = strdup(h.str); return h; } void nhap() { 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(D& h) // Hamtaosaochep { *this=h; } D& operator=(D& h) { this->u = h.u; 283 284 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; clrscr(); h1.nhap(); D h2(h1); cout<<"\n\nH2:"; h2.xuat(); h1.nhap(); cout<<"\n\nH2:"; h2.xuat(); cout<<"\n\nH1:"; h1.xuat(); getch(); } . được dùng hàm tạo sao chép mặc định, mà phải xây dựng cho lớp dẫn xuất một hàm tạo sao chép. 8.2. Cách xây dựng hàm tạo sao chép cho lớp dẫn xuất + Trước. Hàm tạo sao chép của lớp dẫn xuất 8.1. Khi nào cần xây dựng hàm tạo sao chép: 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