Bài giảng lập trình hướng đối tượng - Thầy Cường Học viện bưu chính viễn thông TP HCM
Chương Tính đa hình • Con trỏ Lớp dẫn xuất • Dẫn nhập hàm ảo • Các hàm ảo túy • Áp dụng đa hình Chương 270 Tính đa hình I/ Con trỏ Lớp dẫn xuất 1/ Khái niệm Tính đa hình (polymorphism) hổ trợ hai cách khác C++ Cách 1, đa hình hổ trợ biên dịch chương trình (compiler) thông qua việc tải hàm toán tử Cách 2, đa hình hổ trợ thời điểm thực thi chương trình (run-time) thông qua hàm ảo Cách giúp lập trình viên linh động • Cơ sở hàm ảo đa hình thực thi chương trình trỏ lớp dẫn xuất Chương có khảo sát trỏ, đặc tính trỏ khảo sát chương Nếu p trỏ tới lớp sở, sử dụng p để trỏ tới lớp suy từ lớp sở Chẳng hạn, có hai lớp sở base lớp dẫn xuất derived kế thừa base, phát biểu sau base *p; // base class pointer base base_ob; derived derived_ob; // object of type base // object of type derived // p can, of course, point to base objects p = &base_ob; // p points to base object // p can also point to derived objects without error p = &derived_ob; // p points to derived object Một trỏ lớp sở trỏ tới lớp dẫn xuất lớp sở mà không gây báo lỗi khác kiểu Song truy cập thành phần mà lớp dẫn xuất kế thừa từ lớp sở Bởi trỏ lớp sở biết lớp sở mà thôi, thành phần thêm vào lớp dẫn xuất Chương 271 Tính đa hình • Một trỏ lớp dẫn xuất dùng để truy cập đối tượng lớp sở (Việc sử dụng linh hoạt kiểu dùng để khắc phục hạn chế nói trên, không khuyến khích sử dụng) Các phép toán số học trỏ liên quan đến kiểu liệu mà trỏ khai báo để trỏ đến Do đó, trỏ đến đối tượng lớp dẫn xuất, tăng nội dung trỏ lên Điều không làm cho trỏ đến đối tượng lớp dẫn xuất, mà đến đối tượng lớp sở Ví dụ 1.1 Dùng trỏ lớp sở để truy cập đến lớp dẫn xuất // Demonstrate pointer to derived class #include class base { int x; public: void setx(int i) { x = i; } int getx() { return x; } }; class derived : public base { int y; public: void sety(int i) { y = i; } int gety() { return y; } }; int main() { base *p; base b_ob; derived d_ob; // pointer to base type // object of base // object of derived // use p to access base object p = &b_ob; Chương Tính đa hình 272 p->setx(10); // access base object cout func(); // use derived1's func() Giải thích kết qủa chương trình ? p = &d_ob2; p->func(); // use derived2's func() Using base version of func() : 10 Using derived1's version of func() : 100 Using derived2's version of func() : 20 return 0; @ Kieåu đối tượng trỏ đến xác định phiên hàm ảo thực thi thông qua cách gọi hàm trỏ Điều xác định lúc runtime 2/ Hàm ảo tải hàm Chương 275 Tính đa hình Việc tái định hàm ảo lớp dẫn xuất có tương tự tải hàm không ? Câu trả lời không Số lượng đối số Kiểu liệu đối số Hàm thành phần lớp Hàm tạo Hàm hủy Vị trí Quá tải hàm Cho phép khác biệt Cho phép khác biệt Không bắt buộc Được phép Không Hàm ảo Phải giống Phải giống Bắt buộc Không Có thể Việc tái định hàm ảo lớp dẫn xuất gọi gán thứ tự ưu tiên cao cho hàm 3/ Các hàm ảo phân cấp theo thứ tự kế thừa Nếu lớp dẫn xuất không tái định hàm ảo lớp sử dụng phiên hàm lớp sở Ví dụ 2.2 // Virtual functions are hierarchical #include class base { public: int i; base(int x) { i = x; } virtual void func() { cout