Virtual function (hàm ảo), override và final

 - 

Trong bài học kinh nghiệm trước về con trỏ cùng tsay đắm chiếu tới trường đại lý của những đối tượng dẫn xuất, họ vẫn chu đáo một số trong những ví dụ trong những số đó thực hiện con trỏ hoặc tsay đắm chiếu đến lớp cơ sở tất cả hàm dễ dàng. Tuy nhiên, vào phần đông ngôi trường hợp, bọn họ gặp mặt cần sự việc là nhỏ trỏ cửa hàng hoặc tđê mê chiếu chỉ hoàn toàn có thể Hotline lớp đại lý của hàm, chưa hẳn là lớp dẫn xuất.

Bạn đang xem: Virtual function (hàm ảo), override và final

/*** wesave.vn - Kênh lên tiếng IT bậc nhất Việt Nam**

rBase is a BaseVì rBase là một trong tsi mê chiếu của Base, vì thế nó Hotline Base :: getName(), tuy nhiên nó đích thực tham chiếu cho tới Base của một đối tượng người tiêu dùng đang chế tạo ra.

Trong bài học này, chúng ta đã chỉ cho chính mình cách giải quyết vụ việc này bằng các hàm ảo.


1. Hàm ảo cùng đa hình

Hàm ảo là 1 một số loại hàm quan trọng, Khi được call, vẫn auto phát âm và lựa chọn đúng đối tượng người tiêu dùng cội để Call đúng hàm của đối tượng người tiêu dùng kia thân lớp cửa hàng cùng lớp dẫn xuất. Khả năng này được hotline là nhiều hình. Hàm dẫn xuất được xem như là khớp với lớp đại lý trường hợp nó tất cả thuộc tên, nhiều loại tsay đắm số (mặc dù đó là const) với đẳng cấp trả về của hàm vào lớp các đại lý. Các hàm như vậy được Gọi là ghi đè(overriding).

Để tạo nên một hàm ảo, chỉ việc đặt từ khóa virtual trước khi khai báo hàm.

Dưới đây, ví dụ trên với 1 hàm ảo:

/*** wesave.vn - Kênh đọc tin IT bậc nhất Việt Nam**

rBase is a DerivedVì rBase là 1 trong những tmê mệt chiếu đến lớp Base của một đối tượng người dùng đã tạo ra, Khi rBase.getName() được tiến hành, thường thì nó đã điện thoại tư vấn Base :: getName(). Tuy nhiên, Base :: getName() là ảo, buộc phải công tác đã để ý liệu và tìm đúng đối tượng người tiêu dùng dẫn xuất sẽ kế thừa hàm ảo kia ko. Trong trường đúng theo này, nó đang tìm thấy đối tượngDerived với đã gọi Derived :: getName =()!


Hãy thuộc xem một ví dụ phức hợp hơn một chút:

#include #include class Apublic: virtual std::string_view getName() const return "A"; ; class B: public Apublic: virtual std::string_view getName() const return "B"; ; class C: public Bpublic: virtual std::string_view getName() const return "C"; ; class D: public Cpublic: virtual std::string_view getName() const return "D"; ; int main(){ C c; A &rBase c ; std::cout Bạn nghĩ công tác này sẽ ra sao?

Hãy chú ý vào phương thức buổi giao lưu của nó. Đầu tiên, họ khởi chế tác một đối tượng người tiêu dùng lớp C. rBase là một trong tsi chiếu A, nhưng họ đặt nhằm tsi mê chiếu phần A của đối tượng C. Cuối thuộc, bọn họ Gọi rBase.getName (). rBase.getName() dự trù thành A :: getName(). Tuy nhiên, A :: getName() là ảo, vì chưng vậy trình biên dịch vẫn kiếm tìm với gọi đối tượng người sử dụng cội tốt nhất thân A và C. Trong trường hợp này, đó là C :: getName(). Lưu ý rằng nó sẽ không gọi D :: getName(), bởi vì đối tượng người dùng lúc đầu của bọn họ là C, chưa hẳn D, vì thế chỉ lưu ý những hàm thân A và C.

Kết trái là, công tác của họ đã in ra:

rBase is a C

2. Một ví dụ phức tạp hơn

Hãy nhằm một chiếc nhìn khác về ví dụ Động thiết bị nhưng mà bọn họ đã thao tác vào bài học kinh nghiệm trước. Tại trên đây, lớp học tập ban đầu, cùng với một số mã kiểm tra:

/*** wesave.vn - Kênh biết tin IT hàng đầu Việt Nam**

Fred says ???Garbo says ???Ở phía trên, lớp tương tự với hàm speak() được tạo nên ảo:

/*** wesave.vn - Kênh ban bố IT hàng đầu Việt Nam**

Fred says MeowGarbo says WoofNó hoạt động!

Lúc Review Animal.speak(), lịch trình xem xét rằng Animal :: speak() là 1 trong hàm ảo. Trong ngôi trường thích hợp động vật tsay mê chiếu lớp Animal của vật thể Cat, công tác vẫn chú ý tất cả các phần giữa Animal và Cat giúp thấy liệu nó có thể search thấy một hàm từ đối tượng người sử dụng gốc ko. Trong trường đúng theo đó, nó search thấy Cat :: speak(). Trong ngôi trường vừa lòng động vật tsi mê chiếu lớp Animal của đối tượng Dog, lịch trình đã Gọi hàm Dog :: speak().


Lưu ý rằng chúng ta vẫn tạo nên Animal :: getName() ảo. Như vậy khiến cho getName() không lúc nào bị ghi đnai lưng vào ngẫu nhiên lớp dẫn xuất nào, vì vậy không phải.

Xem thêm: Chuẩn Tốc Độ Ram Ddr3 Là Gì ? Khác Nhau Giữa Ddr3 Và Ddr2 Thông Số Ram Ddr3 Trên Máy Tính Có Ý Nghĩa Gì

Tương tự, ví dụ mảng tiếp sau đây hoạt động nhỏng ước ao đợi:

Cat fred "Fred" ;Cat misty "Misty" ;Cat zeke "Zeke" ; Dog garbo "Garbo" ;Dog pooky "Pooky" ;Dog truffle "Truffle" ; // Set up an array of pointers to animals, và set those pointers to our Cat & Dog objectsAnimal *animals<> &fred, &garbo, &misty, &pooky, &truffle, &zeke ; for (const tự động hóa *animal : animals) std::cout getName() speak() Tạo ra kết quả:

Fred says MeowGarbo says WoofMisty says MeowPooky says WoofTruffle says WoofZeke says MeowMặc mặc dù nhị ví dụ này chỉ áp dụng Cat cùng Dog, ngẫu nhiên lớp nào không giống nhưng bọn họ đem từ Animal cũng trở nên chuyển động với hàm report() với mảng animal nhưng mà không buộc phải sửa thay đổi thêm! Đây có lẽ là ích lợi lớn số 1 của những hàm ảo – năng lực cấu trúc code của doanh nghiệp Theo phong cách nhưng mà những lớp new lên đường đang tự động làm việc với code cũ nhưng mà không cần sửa đổi!

Một lời cảnh báo: những từ của hàm lớp dẫn xuất buộc phải khớp chính xác cùng với từ của hàm ảo phần trong lớp cửa hàng nhằm áp dụng hàm trong lớp dẫn xuất. Nếu hàm lớp dẫn xuất có các loại tđắm đuối số khác biệt, chương trình có thể vẫn đang biên dịch xuất sắc, nhưng hàm ảo sẽ không còn hotline nlỗi muốn đợi của bọn họ.

3. Sử dụng từ khóa virtual

Nếu một hàm được lưu lại là virtual, toàn bộ những phần ghi đè phù hợp cũng được xem là virtual, trong cả khi bọn chúng ko được khắc ghi rõ ràng những điều đó. Tuy nhiên, việc tất cả từ khóa virtual trên những hàm dẫn xuất không gây hại cùng nó đóng trách nhiệp phương châm như một lời kể hữu dụng rằng hàm này là 1 trong hàm ảo chứ chưa hẳn là 1 trong hàm bình thường. Do đó, nói tầm thường là 1 trong những ý tưởng xuất sắc để áp dụng trường đoản cú khóa virtual cho các hàm ảo trong những lớp dẫn xuất mặc dù nó không thực thụ cần thiết.

4. Trả về các các loại hàm ảo

Trong ngôi trường phù hợp thông thường, hình dạng trả về của hàm ảo cùng hàm ghi đnai lưng của chính nó đề xuất khớp. Hãy chăm chú ví dụ sau:

class Basepublic: virtual int getValue() const return 5; ; class Derived: public Basepublic: virtual double getValue() const return 6.78; ;Trong trường đúng theo này, Derived :: getValue() ko được xem như là ghi đnai lưng cân xứng đến Base :: getValue() (nó được xem là một hàm hoàn toàn riêng biệt).

5. Không hotline những hàm ảo từ bỏ các hàm chế tạo ra hoặc hàm hủy

Ở phía trên, Bạn ko nên người ta gọi những hàm ảo tự các hàm chế tạo ra hoặc hàm hủy. Tại sao?

Hãy hãy nhờ rằng khi một lớp Derived được tạo nên, phần Base được tạo ra trước. Nếu các bạn đã call một hàm ảo trường đoản cú hàm tạo ra cơ sở với phần lớp Derived thậm chí là không được sinh sản, thì nó cấp thiết gọi hàm của Derived vì không tồn tại đối tượng Derived được khởi chế tạo ra nhằm Gọi hàm. Trong C ++, nó đang Hotline hàm vào class Base sửa chữa.


Một vụ việc tựa như tồn tại mang lại hàm huỷ. Nếu các bạn Điện thoại tư vấn một hàm ảo vào hàm bỏ của lớp Trung tâm, nó vẫn luôn Điện thoại tư vấn hàm của lớp Cơ sở, cũng chính vì phần Derived của lớp đã trở nên diệt.

Quy tắc: Không khi nào Hotline những hàm ảo tự những hàm sản xuất hoặc hàm diệt.

Xem thêm: Đề Tài Nghiên Cứu Tiếng Anh Là Gì, Vietgle Tra Từ

Những bài tập thực hành thực tế về tính chất nhiều hình trong C++

6. Nhược điểm của những hàm ảo

Vì phần lớn thời gian các bạn sẽ mong mỏi những hàm của mình là ảo, tại vì sao ko làm cho toàn bộ những hàm trsống đề xuất ảo? Câu trả lời là bởi vì nó không tác dụng – việc giải quyết và xử lý một cuộc gọi hàm ảo mất nhiều thời hạn rộng là giải quyết và xử lý một cuộc call thường thì. mà hơn nữa, trình biên dịch cũng đề xuất cấp phát một nhỏ trỏ phú cho từng đối tượng lớp có một hoặc các hàm ảo. Chúng tôi sẽ nói đến điều này nhiều hơn trong những bài học về sau vào của phần này.


Gửi Đánh Giá

Xếp hạng 0 / 5. Số lượng nhận xét 0

Hãy Đánh Giá nhằm ủng hộ cùng góp công ty chúng tôi nâng cấp nội dung bài viết giỏi hơn mang đến bạn!


Chúng tôi xin lỗi bởi bài viết chưa được quality. Chúng tôi đã nâng cấp nó sớm nhất!


Chuyên mục: Chia sẻ