1. Trang chủ
  2. » Luận Văn - Báo Cáo

Bài giảng Ngôn ngữ lập trình: Bài 9 - Lý Anh Tuấn

35 0 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

NGƠN NGỮ LẬP TRÌNH Bài 9: Đa hình Hàm ảo Giảng viên: Lý Anh Tuấn Email: tuanla@tlu.edu.vn Nội dung Cơ hàm ảo ◦ ◦ ◦ ◦ Kết gán muộn Thi hành hàm ảo Khi sử dụng hàm ảo Lớp trừu tượng hàm ảo túy Con trỏ hàm ảo ◦ Sự tương thích kiểu mở rộng ◦ Ép lên ép xuống ◦ Chi tiết hàm ảo Cơ hàm ảo  Đa hình ◦ Liên kết nhiều ngữ nghĩa với hàm ◦ Hàm ảo cung cấp khả ◦ Là nguyên tắc lập trình hướng đối tượng  Ảo ◦ Tồn chất thực tế không tồn  Hàm ảo ◦ Có thể sử dụng trước định nghĩa Ví dụ hình vẽ  Lớp số kiểu hình vẽ ◦ Hình chữ nhật (rectangle), hình trịn (circle), hình ovan (oval), vân vân ◦ Mỗi hình vẽ đối tượng lớp khác  Dữ liệu hình chữ nhật: độ cao, chiều rộng, tâm điểm  Dữ liệu hình trịn: tâm điểm, bán kính Tất dẫn xuất từ lớp cha: Figure  Hàm cần thiết: draw()  ◦ Các thị khác cho hình vẽ Ví dụ hình vẽ: center() Mỗi lớp cần hàm draw khác  Có thể gọi draw lớp:  Rectangle r; Circle c; r.draw(); //Gọi hàm draw lớp Rectangle c.draw(); // Gọi hàm draw lớp Circle  Lớp cha Figure bao gồm hàm áp dụng cho tất hình vẽ; chẳng hạn: center(): di chuyển hình vẽ vào tâm hình ◦ Xóa hình ban đầu, sau vẽ lại ◦ Do Figure::center() gọi hàm draw để vẽ lại ◦ Vấn đề: Gọi hàm draw() từ lớp nào? Ví dụ hình vẽ: Hình    Xét kiểu hình vẽ sau: lớp Triangle dẫn xuất từ lớp Figure Hàm center() kế thừa từ Figure ◦ Nó có làm việc với triangle khơng? ◦ Nó sử dụng draw() khác với hình khác ◦ Nó sử dụng Figure::draw()  khơng làm việc với triangle Cần hàm center() kế thừa sử dụng hàm Triangle::draw() hàm Figure::draw() ◦ Nhưng lớp Triangle chí cịn chưa viết viết Figure::center() Ví dụ hình vẽ: Hình ảo Câu trả lời sử dụng hàm ảo  Nói cho biên dịch:  ◦ Không biết hàm thi hành ◦ Đợi sử dụng chương trình ◦ Sau nhận thi thành từ thể đối tượng  Được gọi kết gán muộn kết gán động ◦ Hàm ảo thi hành kết gán muộn Một ví dụ khác  Chương trình lưu trữ hồ sơ cửa hàng phụ tùng ô tô ◦ ◦ ◦ ◦ Theo dõi giao dịch Chưa biết biết tất giao dịch Ban đầu có giao dịch bán lẻ Sau đó: Giao dịch giảm giá, thư đặt hàng, vân vân  Phụ thuộc vào nhân tố khác bên cạnh giá thuế Hàm ảo: Phụ tùng tơ  Chương trình phải: ◦ Tính tốn doanh thu tổng cộng hàng ngày ◦ Tính tốn giao dịch lớn nhất/nhỏ ngày ◦ Có thể tính giá trị trung bình giao dịch ngày  Tất đến từ hóa đơn riêng lẻ ◦ Nhưng nhiều hàm tính tốn hóa đơn thêm vào sau  Khi kiểu giao dịch khác thêm vào  Do hàm tính tốn hóa đơn ảo Định nghĩa lớp Sale  class Sale { public: Sale(); Sale(double thePrice); double getPrice() const; virtual double bill() const; double savings(const Sale& other) const; private: double price; }; 10 Lớp sở trừa tượng  Hàm ảo túy khơng địi hỏi phải định nghĩa ◦ Bắt tất lớp dẫn xuất định nghĩa phiên riêng chúng  Lớp với nhiều hàm ảo túy là: lớp sở trùy tượng ◦ Có thể sử dụng lớp sở ◦ Khơng có đối tượng tạo từ  Vì khơng có định nghĩa hồn chỉnh cho tất thành viên  Nếu lớp dẫn xuất thất bại việc định nghĩa tất hàm ảo túy ◦ Nó lớp sở trừu tượng 21 Tương thích kiểu mở rộng  Biết rằng: Derived lớp dẫn xuất Base ◦ Các đối tượng Derived gán cho đối tượng kiểu Base ◦ Nhưng ngược lại khơng  Xét ví dụ trước: ◦ Một DiscountSale Sale ngược lại khơng 22 Ví dụ tương thích kiểu mở rộng  class Pet { public: string name; virtual void print() const; }; class Dog : public Pet { public: string breed; virtual void print() const; }; 23 Lớp Pet Dog Bây cung cấp khai báo: Dog vdog; Pet vpet;  Lưu ý biến thành viên name breed public  ◦ Chỉ nhằm mục đích ví dụ, khơng điển hình 24 Sử dụng lớp Pet Dog  Một chó thú cưng: ◦ vdog.name = "Tiny"; vdog.breed = "Great Dane"; vpet = vdog; ◦ Những lệnh phép  Có thể gán giá trị cho kiểu cha, ngược lại khơng ◦ Một thú cưng khơng phải chó 25 Vấn đề tách lớp  Lưu ý giá trị gán cho vpet trường breed ◦ coutbreed = "Great Dane"; ppet = pdog;  Không thể truy cập trường breed đối tượng trỏ tới ppet: cout breed; //Khong hop le  28 Ví dụ vấn đề tách lớp  Phải sử dụng hàm thành viên ảo: ppet->print(); ◦ Gọi hàm thành viên print lớp Dog  Bởi ảo  C++ đợi để xem đối tượng trỏ ppet trỏ tới trước gọi kết gán 29 Hàm hủy ảo Nhắc lại: hàm hủy cần để hủy cấp phát liệu cấp phát động  Xét:  Base *pBase = new Derived; … delete pBase; ◦ Sẽ gọi hàm hủy lớp sở trỏ tới đối tượng lớp Derived ◦ Khai báo hàm hủy virtual để chỉnh sửa vấn đề  Có thể để tất hàm hủy ảo 30 Ép kiểu  Xét: Pet vpet; Dog vdog; … vdog = static_cast(vpet); //Không hợp lệ!  Không thể ép thú cưng thành chó, nhưng: vpet = vdog; // Legal! vpet = static_cast(vdog); //Also legal!  Ép kiểu lên thực ◦ Từ kiểu hậu duệ đến kiểu tổ tiên 31 Ép kiểu xuống  Ép kiểu xuống nguy hiểm ◦ Ép từ kiểu tổ tiên xuống kiểu hậu duệ ◦ Giả sử thơng tin thêm vào ◦ Có thể thực với dynamic_cast: Pet *ppet; ppet = new Dog; Dog *pdog = dynamic_cast(ppet);  Hợp lệ, nguy hiểm  Ép kiểu xuống sử dụng do: ◦ Phải theo dõi tất thông tin thêm vào ◦ Tất hàm thành viên phải ảo 32 Công việc nội hàm ảo  Khơng cần biết sử dụng ◦ Quy tắc che dấu thông tin  Bảng hàm ảo ◦ Bộ biên dịch tạo ◦ Có trỏ cho hàm thành viên ảo ◦ Trỏ tới vị trí mã lệnh hàm  Các đối tượng lớp có trỏ ◦ Các trỏ trỏ tới bảng hàm ảo 33 Tóm tắt  Kết gán muộn hỗn việc định hàm thành viên gọi chương trình chạy ◦ Trong C++ hàm ảo sử dụng kết gán muộn  Các hàm ảo túy khơng có định nghĩa ◦ Các lớp có hàm ảo túy trừu tượng ◦ Không có đối tượng tạo từ lớp trừu tượng ◦ Được sử dụng làm sở cho lớp khác dẫn xuất 34 Tóm tắt  Đối tượng lớp dẫn xuất gán cho đối tượng lớp sở ◦ Các thành viên lớp sở bị mất: vấn đề tách lớp  Phép gán trỏ đối tượng động ◦ Cho phép chỉnh sửa vấn đề tách lớp  Khai báo tất hàm hủy ảo ◦ Áp dụng tốt cho việc lập trình ◦ Đảm bảo nhớ hủy cấp phát 35

Ngày đăng: 12/09/2023, 01:36

Xem thêm: