Từ khóa virtual trong C++

Từ khóa Virtual trong C++

Tác dụng của từ khoá virtual, tại sao cần có virtual function.

Một số tài liệu có viết công dụng của Virtual Function như sau:

Virtual Function là để khai báo một function ở class cha (base class) mà sau đó các class kế thừa (derived class) có thể override function đó.

Nhưng chờ đã, có gì không ổn ở chỗ này, nếu chỉ là để override thôi thì mình hoàn toàn có thể khai báo function ở base class mà không cần virtual thì vẫn được cơ mà. Vậy ko lẽ đồng chí Virtual Function này vô dụng? Để làm rõ vấn đề cũng như hạn chế buồn ngủ vì phải đọc quá nhiều chữ, chúng ta thử xét ví dụ nhỏ sau:

Output sẽ ra như thế này:

Nếu chỉ xét đến đây thì cậu virtual chắc sẽ hơi buồn vì mọi chuyện có vẻ vẫn ổn mà không cần đến sự có mặt của nó. Vì vậy chúng ta thử xét tiếp 1 ví dụ khác để làm chỗ cho virtual toả sáng một chút.

Lần này output sẽ là như thế này:

Đến đây thì chắc không cần phải quá tinh mắt bạn cũng đã nhận ra vấn đề rồi đúng không. Mặc dù andy được tạo ra từ constructor của class YoungBuffalo thế nhưng nó hành xử lại như thể nó là một Buffalo. Thế nhưng ví dụ này trông hơi bị thiếu thông minh vì chả mấy ai khai báo Buffalo *andy = new YoungBuffalo(); như này để tự làm khó mình cả. Mình sẽ xét một ví dụ thực tế hơn chút nữa.

Output sẽ vẫn lại là:

Lúc này thì vấn đề thực sự đã rõ rồi, vì vậy chúng ta sẽ fix với vấn đề này với virtual như sau:

Output:

Hoàn hảo! Lần này thì ai đã làm việc của người đó, Buffalo đã ăn cỏ, và YoungBuffalo đã gõ bàn phím. Ta sẽ đi đến mục tiếp theo.

Virtual Destructor

Virtual destructor cũng giống như các hàm virtual bình thường và được khai báo bằng cách thêm từ khoá virtual đằng trước hàm destructor. Nhưng trước khi học cách sử dụng virtual destructor, chúng ta sẽ nhìn qua một ví dụ mà không có virtual destructor.

Output:

Chúng ta có thể thấy ngay là destructor của class Cat đã không được gọi, mặc dù tom được khởi tạo bằng constructor của class Cat. Điều này thật sự rất nguy hiểm, vì destructor của class Cat không được gọi nên các đối tượng riêng của lớp đó cũng không được giải phóng và vì thế object tom chỉ được giải phóng 1 phần tài nguyên, điều này gây ra rò rỉ bộ nhớ (hiện tượng bộ nhớ đã được cấp phát không thu hồi lại được). Để khắc phục chúng ta thêm từ khoá virtual vào trước destructor của base class.

Output:

Virtual destructor là một thứ rất quan trọng khi bạn làm việc với C++, nếu bạn có ý định cho phép kế thừa class mà bạn đang viết thì bạn bắt buộc phải thêm virtual destructor cho class đó, ngược lại thì bạn đang ngầm ám chỉ rằng class của bạn không cho phép kế thừa. Điều này tương đương với từ khoá final trong Java. Nếu bạn thấy một class không có virtual destructor, đơn giản là đừng có kế thừa nó, vì nó đi không đúng với ý định của người viết ra class, và có thể gây ra thiệt hại hệ thống nếu bạn cố tình bỏ qua.

Tham khảo

Why do we need Virtual Methods in C++?
When to use virtual destructors?

Từ Kipalog

Leave a Reply

Be the First to Comment!

Notify of
avatar
wpDiscuz