HÀM ẢO (VIRTUAL FUNCTION) TRONG LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG VỚI C++

Ở bài này, chúng ta sẽ tìm hiểu hàm ảo (virtual function) trong C++. Bài này có các kiến thức liên quan đến con trỏ đối tượng. Các bạn có thể đọc lại bài Khai báo và sử dụng con trỏ đối tượng trong C++ để xem lại kiến thức đó.

Bạn đang xem: Hàm Ảo (Virtual Function) Trong Lập Trình Hướng Đối Tượng Với C++

1. Hàm ảo (virtual function) là gì?

Hàm ảo (virtual function) là một hàm thành viên trong lớp cơ sở mà lớp dẫn xuất khi kế thừa cần phải định nghĩa lại.Hàm ảo được sử dụng trong lớp cơ sở khi cần đảm bảo hàm ảo đó sẽ được định nghĩa lại trong lớp dẫn xuất. Việc này rất cần thiết trong trường hợp con trỏ có kiểu là lớp cơ sở trỏ đến đối tượng của lớp dẫn xuất.Để hiểu tại sao phải sử dụng hàm ảo, chúng ta cùng xem xét một ví dụ:class Base{public:void print(){coutLớp Derived kế thừa public từ lớp Base. Chúng ta tạo một con trỏ (pointer) có kiểu là lớp Base trỏ đến một đối tượng của lớp Derived. Sau đó, gọi hàm print() thì bản chất là gọi hàm print() của lớp Base. Mà chúng ta muốn là phải gọi đến hàm print() của lớp Derived bởi con trỏ đang trỏ đến đối tượng của lớp Derived.void main(){Derived derived1;Base* base1 = &derived1;//calls function of Base classbase1->print();system("pause");}Kết quảBase classĐể tránh trường hợp này, chúng ta khai báo hàm print() trong lớp Base là một hàm ảo. Lúc này, lớp dẫn xuất phải định nghĩa lại hàm ảo đó. Khi gọi hàm print() thông qua con trỏ thì sẽ gọi đến hàm được định nghĩa lại trong lớp dẫn xuất.Hàm ảo là một phần không thể thiếu để thể hiện tính đa hình trong kế thừa được hỗ trợ bởi nguồn ngữ C++.

Xem thêm: Từ Vựng Về Bộ Môn Cầu Lông Tiếng Anh Là Gì, Vietgle Tra Từ

Lưu ý: Con trỏ của lớp cơ sở có thể chứa địa chỉ của đối tượng thuộc lớp dẫn xuất, nhưng ngược lại thì không được.

2. Định nghĩa hàm ảo (virtual function)

Sử dụng từ khóa virtual để định nghĩa một hàm ảo trong lớp cơ sở. Lớp dẫn xuất kế thừa từ lớp cơ sở phải định nghĩa lại hàm ảo.#include using namespace std;class Base{public:virtual void print(){//virtual functioncoutprint();system("pause");}Kết quảDerived class
*

Hàm ảo chỉ khác hàm thành phần thông thường khi được gọi từ một con trỏ. Sử dụng hàm ảo khi muốn con trỏ đang trỏ tới đối tượng của lớp nào thì hàm thành phần của lớp đó sẽ được gọi mà không xem xét đến kiểu của con trỏ.

3. Ví dụ sử dụng hàm ảo

#include #include using namespace std;class Animal{private:string type;public: // constructor to initialize type Animal(){type = "Animal";} // declare virtual function virtual string getType(){ return type; }};class Dog : public Animal{private:string type;public: // constructor to initialize type Dog(){type = "Dog";} string getType(){ return type; }};class Cat : public Animal{private:string type;public: // constructor to initialize type Cat(){type = "Cat";} string getType(){ return type; }};void print(Animal* ani) { coutgetType()Kết quảAnimal: AnimalAnimal: DogAnimal: CatLớp Animal là lớp cơ sở của lớp DogCat. Tạo các con trỏ animal1, dog1, cat1 có kiểu là Animal trỏ để các đối tượng của lớp Animal, Dog, Cat. Một hàm ảo getType() được khai báo trong lớp cơ sở Animal. Các lớp dẫn xuất DogCat định nghĩa lại hàm này.Khi hàm print(animal1) được gọi, con trỏ trỏ đến một đối tượng của lớp Animal. Hàm ảo getType() của lớp Animal sẽ thực thi.Khi hàm print(dog1) được gọi, con trỏ trỏ đến một đối tượng của lớp Dog. Hàm ảo getType() được định nghĩa là trong lớp Dog được gọi.Khi hàm print(cat1) được gọi, con trỏ trỏ đến một đối tượng của lớp Cat. Hàm ảo getType() được định nghĩa là trong lớp Cat được gọi.
Bài trước và bài sau trong môn học>" data-wpel-link="internal">Hàm thuần ảo (pure virtual function) và lớp trừu tượng (abstract class) trong C++ >>