Virtual Destructor Trong C++

Giới thiệu

Phương pháp lập trình hướng đối tượng Object-Oriented Programming có 4 tính chất: Tính trừu tượng hóa, tính đóng gói, tính kế thừa, tính đa hình. Trong đó tính đa hình được thể hiện qua con trỏ và hàm ảo (virtual function). Nếu các bạn biết tính đa hình thì chắc chắn hàm ảo khá là quen thuộc. Nhưng khái niệm phương thức hủy ảo có lẽ là một khái niệm khá mới mẻ. Nó được định nghĩa như thế nào, chức năng, sử dụng nó ra sao thì bài viết này tác giả sẽ trình bày chi tiết một cách cụ thể.

Tiền đề bài viết

Bài viết này xuất phát từ sở thích chia sẽ kiến thức của tác giả. Bài viết này gửi tới những lập trình viên đang đặt ra những câu hỏi như Virtual Destructor là gì? Vì sao cần phải dùng nó?…

Destructor

Destructor là một phương thức của một lớp và tự động được gọi trước khi đối tượng bị thu hồi (thoát khỏi phạm vi, chương trình kết thúc, sử dụng delete). Vì đa số chúng ta sử dụng phương thức này để thực hiện dọn dẹp tài nguyên của đối tượng (tránh trường hợp lost memory) nên nó được gọi là phương thức hủy.

Phương thức hủy được khai báo có tên trùng với tên lớp và thêm kí tự ~ ở trước tên phương thức và không có giá trị trả về.

Virtual Destructor

Trong một lớp thì Destructor có thể đánh dấu làm hàm ảo còn Constructor thì không được đánh dấu là hàm ảo.

Xét một vài ví dụ để làm rõ Virtual Destructor. Ví dụ chúng ta có một lớp cha Base và một lớp con Derived được hiện thực như dưới đây.

Trường hợp 1: Phương thức lớp cha không đánh dấu Virtual

Phương thức hủy lớp cha không được đánh dấu là hàm ảo:

Hàm main thực hiện upcasting từ lớp con lên lớp cha.

Sau khi Build và Debug chúng ta thấy chỉ có dòng “Destructor Base” được xuất ra, có nghĩa là chỉ hàm phương thức lớp cha được gọi nhưng phương thức của lớp con không được gọi. Dẫn đến mất mát bộ nhớ.

Xét tiếp ví dụ dưới đây. Tương tự như ví dụ trên nhưng có sửa đổi ở lớp Derived

Hàm main vẫn giữ nguyên như ví dụ ta xét ở đầu.

Với lớp con như trên thì mặc dù chúng ta có định nghĩa phương thức để giải phóng m_array nhưng phương thức của lớp con không được gọi. Có nghĩa là chúng ta đã mất đi 1024*4 bytes bộ nhớ.

Trường hợp 2: Phương thức lớp cha có đánh dấu Virtual

Phương thức lớp cha được đánh dấu là phương thức ảo:

Thực hiện hàm main giống như trường hợp 1

Bulid và Debug thì chương trình xuất ra hai dòng là

Như vậy là phương thức hủy của lớp con được gọi trước sau đó mới gọi phương thức hủy lớp cha, đúng như chúng ta mong muốn. Tránh được tình trạng mất bộ nhớ.

Qua bài viết này hy vọng tác giả đang mang đến cho các bạn một kiến thức khá bổ ích về Virtual Destructor. Nếu có bất cứ thắc mắc nào các bạn có thể để lại bình luận phía dưới hoặc liên hệ với tác giả với tác giả để được giải đáp sớm nhất.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.