Chương 4: Đa năng hoá toán tử

 Khái niệm đa năng hóa toán tử  Đa năng hóa toán tử một ngôi (++,--)  Đa năng hóa toán tử hai ngôi (+,-,*,/, )  Định nghĩa lại phép gán (=)  Đa năng hóa toán tử nhập/xuất (>>,<<)

pdf29 trang | Chia sẻ: lylyngoc | Lượt xem: 3242 | Lượt tải: 3download
Bạn đang xem trước 20 trang tài liệu Chương 4: Đa năng hoá toán tử, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
ĐH CÔNG NGHỆ THÔNG TIN Số tiết lý thuyết: 45 tiết Số tiết thực hành: 30 tiết 1 2 Chương 1: Tổng quan về OOP Chương 2: Lớp & đối tượng Chương 3: Hàm và hàm đa năng trong OOP Chương 4: Đa năng hóa toán tử Chương 5: Sự kế thừa và tính đa hình  Nội dung môn học: 3 Khái niệm đa năng hóa toán tử Đa năng hóa toán tử một ngôi (++,--) Đa năng hóa toán tử hai ngôi (+,-,*,/,…) Định nghĩa lại phép gán (=) Đa năng hóa toán tử nhập/xuất (>>,<<)  Chương 4: Đa năng hoá toán tử 4 Khái niệm đa năng hóa toán tử  Khái niệm  Ví dụ  Cú pháp  Đặc điểm  Khái niệm: Là khả năng kết hợp một toán tử đã có (+,- ,*,/,>,<,..) với một hàm thành viên và dùng nó với các đối tượng của lớp như là những toán hạng. Ví dụ: Ưu điểm của đa năng hoá toán tử? Giúp cho chương trình dễ hiểu và dễ truy tìm lỗi  Chương 4: Đa năng hoá toán tử void main(){ Phanso a,b,c,d; c=a.Cong(b); d=c.Nhan(a.Cong(b)) } void main(){ Phanso a,b,c,d; c=a+b; d=(a+b)*c; }   5 Khái niệm đa năng hóa toán tử  Khái niệm  Ví dụ  Cú pháp  Đặc điểm  Cú pháp: operator@(DS_đối số) Trong đó: @ là toán tử cần đa năng Ví dụ: Đặc điểm:  Không được phép thay đổi chức năng cơ bản,ý nghĩa nguyên thủy của toán tử hoặc thay đổi thứ tự ưu tiên của chúng.  Các toán tử không thể đa năng hóa:  Chương 4: Đa năng hoá toán tử Cách khai báo trước: Phanso cong(Phanso) Cách khai báo đa năng: Phanso operator+(Phanso) . .* :: ?: sizeof 6 Khái niệm đa năng hóa toán tử Đa năng hóa toán tử một ngôi (++,--) Đa năng hóa toán tử hai ngôi (+,-,*,/,…) Định nghĩa lại phép gán (=) Đa năng hóa toán tử nhập/xuất (>>,<<)  Chương 4: Đa năng hoá toán tử 7 Đa năng hóa toán tử một ngôi (++,--)  Khái niệm  Đặc điểm  Cú pháp  Ví dụ Khái niệm: Toán tử một ngôi là gì? Đặc điểm: Các toán tử này được sử dụng theo 2 cách: toán tử đứng trước (prefix) (++a) hay toán tử đứng sau (postfix) (a++) Ví dụ: cho biết kết quả của CT sau  Chương 4: Đa năng hoá toán tử void main(){ int a,b; a=5; a++; cout<<a; ++a; cout<<a; } void main(){ int a,b; a=5; b=++a; cout<<a<<" "<<b; a=5; b=a++; cout<<a<<" "<<b; } // a=6 // a=7 // a=6, b=6 // a=6, b=5 8 Đa năng hóa toán tử một ngôi (++,--)  Khái niệm  Đặc điểm  Cú pháp  Ví dụ  Cú pháp khai báo trong lớp:  Toán tử đứng trước (prefix): operator++()  Toán tử đứng sau (postfix): operator++(int) Định nghĩa bên ngoài lớp: ::operator++() { …. } Ví dụ:  Chương 4: Đa năng hoá toán tử Tham số int được gọi là tham số giả (chỉ định toán tử đứng sau) 9  Chương 4: Đa năng hoá toán tử class Phanso{ private: int tu,mau; public: Phanso(int t=0,int m=1); Phanso operator++(); Phanso operator++(int); void xuat(); }; Phanso::Phanso(int t,int m){ tu=t; mau=m; } Phanso Phanso::operator++(){ tu=tu+mau; return *this; } Phanso Phanso::operator++(int){ Phanso temp=*this; tu=tu+mau; return temp; } void Phanso::xuat(){ cout<<tu<<"/"<<mau<<endl; } void main(){ Phanso a(1,2),b; a++; a.xuat(); ++a; a.xuat(); b=++a; a.xuat(); b.xuat(); b=a++; a.xuat(); b.xuat(); cout<<endl; system("pause"); } // KQ: a=3/2 // KQ: a=5/2 // KQ: a=7/2 và b=7/2 // KQ: a=9/2 và b=7/2 10 Khái niệm đa năng hóa toán tử Đa năng hóa toán tử một ngôi (++,--) Đa năng hóa toán tử hai ngôi (+,-,*,/,…) Định nghĩa lại phép gán (=) Đa năng hóa toán tử nhập/xuất (>>,<<)  Chương 4: Đa năng hoá toán tử 11 Đa năng hóa toán tử hai ngôi  Khái niệm  Cú pháp  Ví dụ Khái niệm: Toán tử hai ngôi là gì?  Cú pháp:  Cách 1: dùng 1 đối số operator(đối số thứ hai)  Cách 2: dùng 2 đối số bằng cách dùng hàm bạn friend friend operator ( đối số thứ nhất,đối số thứ hai) Ví dụ: Xây dựng lớp phân số giải quyết các trường hợp sau: Phanso a(1,2),b(3,2),c; c=a+b; c=a+5; c=5+a;  Chương 4: Đa năng hoá toán tử 12  Chương 4: Đa năng hoá toán tử  Cách 1: dùng 1 đối số class PS{ private: int tu,mau; public: PS(int t=0,int m=1){tu=t;mau=m;} PS operator+(PS); }; PS PS:: operator+(PS p){ PS kq; kq.tu=tu*p.mau+p.tu*mau; kq.mau=mau*p.mau; return kq; } void main(){ PS a(1,2),b(1,2),c(3,4),d; d=a+b+c; }  Cách 2: dùng hàm bạn friend class PS{ private: int tu,mau; public: PS(int t=0,int m=1){tu=t;mau=m;} friend PS operator+(PS,PS); }; PS operator+(PS a,PS b){ PS kq; kq.tu=a.tu*b.mau+a.tu*b.mau; kq.mau=a.mau*b.mau; return kq; } void main(){ PS a(1,2),b(1,2),c(3,4),d; d=a+b+c; } 13 Khái niệm đa năng hóa toán tử Đa năng hóa toán tử một ngôi (++,--) Đa năng hóa toán tử hai ngôi (+,-,*,/,…) Định nghĩa lại phép gán (=) Đa năng hóa toán tử nhập/xuất (>>,<<)  Chương 4: Đa năng hoá toán tử 14 Định nghĩa lại phép gán (=)  Khái niệm  Lý do?  Cú pháp  Ví dụ Khái niệm: Phép gán “=” là gì?  Lý do: Định nghĩa lại phép gán “=” để giải quyết các trường hợp sau:  Vấn đề con trỏ Null trong cấp phát động(Buổi 2)  Vấn đề chuyển đổi kiểu (Buổi 2)  Cú pháp: operator=(DS_Đối số_nếu có) Ví dụ:  Chương 4: Đa năng hoá toán tử 15  Chương 4: Đa năng hoá toán tử  Vấn đề con trỏ Null trong cấp phát động: class String{ private: char *p; public: String(char *s=“”){p=strdup(s);} ~String(){delete p;} }; void main(){ String s1(“Hello”); String s2; s2=s1; } Hello s1:p s2:p  Giải quyết: class String{ private: char *p; public: String(char *s=“”){p=strdup(s);} String& operator=(const String&); ~String(){delete p;} }; String& String::operator=(const String &s){ p=strdup(s.p); return (*this); } Hello Hello s1:p s2:p Khi kết thúc chương trình s1 giải phóng vùng nhớ làm cho s2 trỏ vào vùng nhớ NULL 16  Chương 4: Đa năng hoá toán tử  Vấn đề chuyển đổi kiểu: class PS{ private: int tu,mau; public: PS(int t=0,int m=1){ tu=t;mau=m; } }; void main(){ PS a(1,2); PS b=3; }  Giải quyết: class PS{ private: int tu,mau; public: PS(int t=0,int m=1){ tu=t;mau=m; } PS operator=(int); }; PS PS::operator=(int t){ return PS(t,1); } void main(){ PS a(1,2); PS b=3; } Khi gặp câu lệnh gán như trên, CT lần lượt thực hiện các thao tác sau:  Có định nghĩa phép gán “=” tương ứng hay không?  Hàm khởi tạo chuyển đổi kiểu có hay không? // Error 17 Khái niệm đa năng hóa toán tử Đa năng hóa toán tử một ngôi (++,--) Đa năng hóa toán tử hai ngôi (+,-,*,/,…) Định nghĩa lại phép gán (=) Đa năng hóa toán tử nhập/xuất (>>,<<)  Chương 4: Đa năng hoá toán tử 18 Đa năng hóa toán tử nhập/xuất (>>,<<)  Khái niệm  Cú pháp  Ví dụ Khái niệm: Là cách thức để các toán tử nhập/xuất (>>,<<) có thể thực hiện được trên các đối tượng người dùng.  Cú pháp:  Đa năng hóa toán tử xuất:<< friend ostream& operator &)  Đa năng hóa toán tử nhập:>> friend istream& operator >>(istream &, &) Ví dụ:  Chương 4: Đa năng hoá toán tử 19  Chương 4: Đa năng hoá toán tử Đa năng hoá toán tử nhập/xuất (>>,<<) cho lớp phân số: void main(){ PS a(1,2); PS b; cin>>b; cout<<b; } class PS{ private: int tu,mau; public: PS(int t=0,int m=1){tu=t;mau=m;} friend ostream& operator <<(ostream &,const PS&); friend istream& operator >>(istream &, PS&); }; ostream& operator <<(ostream & os,const PS& p){ os<<p.tu<< “/ "<<p.mau; return os; } istream& operator >>(istream & is, PS& p){ cout<< "Nhap tu: "; is>>p.tu; cout<< "Nhap mau: "; is>>p.mau; return is; } ĐH CÔNG NGHỆ THÔNG TIN 20 ĐH CÔNG NGHỆ THÔNG TIN 21 22 Câu 1: Cho Phát biểu nào sau đây là ĐÚNG trong đa năng hoá toán tử (operator overloading)  Bài tập trắc nghiệm A. Có thể thay đổi kết quả thực hiện của các toán tử trên các kiểu dữ liệu cơ sở (built-in). B. Có thể định nghĩa thêm toán tử mới ngoài những toán tử đã có trong C++. C. Có thể thay đổi số lượng tham số (số ngôi) của các toán tử. D. Không thể thay đổi độ ưu tiên của các toán tử. 23 Câu 2: Toán tử nào có thể được viết lại (overloaded trong C++  Bài tập trắc nghiệm A. = (toán tử gán) B. ?: (toán tử điều kiện) C. sizeof (toán tử xác định kích thước dữ liệu) D. :: (toán tử phạm vi) 24 Câu 3: Để đa năng hoá toán tử >> dùng để nhập các thông tin của đối tượng thuộc class Data (ví dụ như: cin>>dataToPrint). Dòng đầu tiên trong hàm cài đặt toán tử là:  Bài tập trắc nghiệm A. ostream operator>>(ostream &input,const Data &dataToPrint) B. ostream operator>>(istream &input,const Data &dataToPrint) C. istream &operator>>(istream &input, Data dataToPrint) D. istream &operator>>(istream &input, Data &dataToPrint) 25 Câu 4: Xét đoạn chương trình khai báo class Data như sau: class Data{ private: int a; public: Data operator --(int); void Giam(){ a=a-1;} };  Bài tập trắc nghiệm A Data Data::operator – (int){ Data temp=*this; Giam(); return *temp; } Phần cài đặt toán tử -- nào sau đây là đúng B Data Data::operator – (int){ Giam(); Data temp=*this; return temp; } C Data Data::operator – (int){ Data temp=*this; Giam(); return temp; } D Data Data::operator – (int){ Data temp=*this; temp.Giam(); return this; } 26 Câu 5: Khi thực thi đoạn chương trình kết quả sẽ là: class Phanso{ private: int tuso,mauso; public: Phanso(int t=0,int m=1){ tuso=t; mauso=m; cout<< " ("<<tuso<< "/ "<<mauso<< ") "<<endl; } Phanso(const Phanso &x){ tuso=x.tuso; mauso=x.mauso; cout<< " ("<<tuso<< "/ "<<mauso<< ") "<<endl; } Phanso operator++(int){ Phanso old = *this; tuso += mauso; return old; } };  Bài tập trắc nghiệm A. Kết quả in ra là (1/2)(3/2) B. Chương trình thực thi mà không in ra kết quả gì C. Chương trình bị lỗi khi biên dịch D. Kết quả in ra là (1/2)(1/2) (1/2) void main(){ Phanso x(1,2); Phanso y=x++; }; ĐH CÔNG NGHỆ THÔNG TIN 27 28 ĐÁP ÁN:  Đáp án bài tập trắc nghiệm Câu Đáp án Giải thích 1 D 2 A Các toán tử không thể định nghĩa lại: 3 D ostream: xuất (loại A,B) istream: nhập (nhập tức dữ liệu phải thay đỗi nên phải dùng tham chiếu: & ở cả 2 tham số)  đáp án D 4 C b=--a (trừ trước gán sau) b=a-- (gán trước trừ sau: tức giá trị b phải bằng giá trị a) 5 D Phanso x(1,2); // Xuất 1 lần do gọi hàm khởi tạo Phanso old = *this; // Xuất 1 lần do gọi hàm khởi tạo sao chép Phanso operator++(int) // Xuất 1 lầb do gọi hàm khởi tạo sao chép . .* :: ?: sizeof 29 ĐÁP ÁN:  Đáp án bài tập trắc nghiệm Câu Đáp án Giải thích 6 D Hàm ảo phải là hàm thành viên của lớp. 7 A Các khái niệm B,D,C là những khái niệm SAI 8 D Câu lệnh d.BaseA::Print(); đã xác định rõ hàm Print() là của lớp A 9 C pb là con trỏ lớp cơ bản nên có thể trỏ tới đối tượng là lớp dẫn xuất nhưng ngược lại thì không. 10 C Derive d; d là đối tượng lớp dẫn xuất nên trỉnh tự gọi hàm khởi tạo: lớp cơ bản gọi trước, lớp dẫn xuất gọi sau.