Khái niệm Destructor (Hàm hủy) đóng vai trò thiết yếu trong việc viết code C++ an toàn, tránh rò rỉ tài nguyên. Bài viết từ InterData sẽ cùng bạn khám phá chi tiết: Hàm hủy – Destructor là gì, tìm hiểu cú pháp của hàm hủy và các đặc điểm của Destructor trong lập trình C++. Đọc ngay!
Hàm hủy – Destructor là gì?
Khi bước chân vào thế giới lập trình C++, bạn sẽ gặp Destructor, hay còn gọi là hàm hủy. Đây là một phương thức đặc biệt trong class của bạn. Nó được hệ thống tự động gọi ra vào đúng thời điểm đối tượng của bạn “kết thúc”, sau khi hoàn thành nhiệm vụ của mình.

Vai trò cốt lõi của hàm hủy vô cùng quan trọng: đó là “dọn dẹp” những gì đối tượng đã dùng. Tưởng tượng đối tượng thuê bộ nhớ động, mở file hay kết nối mạng, chính hàm hủy sẽ là người có trách nhiệm giải phóng chúng một cách gọn gàng.
Mục đích chính của hàm hủy là đảm bảo không có tài nguyên nào bị bỏ quên sau khi đối tượng không còn cần đến nữa. Điều này giúp ngăn chặn tình trạng rò rỉ bộ nhớ (memory leak) hoặc rò rỉ các tài nguyên hệ thống khác, giữ cho chương trình ổn định và hiệu quả.
Cú pháp của hDestructor trong C++
Cú pháp của hàm hủy (Destructor) trong C++ như sau:
Cú pháp:
1 |
|
Ví dụ cụ thể là lớp nhân viên, thì chúng ta sẽ tạo hàm hủy cho lớp nhân viên như sau:
Ví dụ:
1 2 3 4 |
|
Ví dụ về hàm Destructor trong C++
Chúng ta cùng xem xét một ví dụ đơn giản nhất về hàm hủy trong C++ như sau:
Ví dụ:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Kết quả:
Ham xay dung duoc goi Ham xay dung duoc goi Ham huy duoc goi Ham huy duoc goi
Hàm hủy Destructor hoạt động như thế nào?
Destructor (hàm hủy) được tự động gọi khi một đối tượng ra khỏi phạm vi hoạt động hoặc bị xóa một cách tường minh. Các bước trong quá trình hoạt động của destructor bao gồm:
- Khi một đối tượng ra khỏi phạm vi hoạt động – ví dụ, khi kết thúc một hàm hoặc một khối lệnh, hoặc khi từ khóa
delete
được sử dụng để xóa một đối tượng được cấp phát động — thì destructor sẽ được kích hoạt. - Hàm destructor sẽ được gọi và đoạn mã bên trong nó sẽ được thực thi.
- Sau khi hàm destructor thực thi xong, bộ nhớ của đối tượng đó sẽ được giải phóng (trong các ngôn ngữ có quản lý bộ nhớ thủ công như C++), hoặc được đánh dấu để thu gom rác (garbage collection) trong các ngôn ngữ như Java và C#.
Các đặc điểm cơ bản của Destructor
Dưới đây là các đặc điểm chính của một destructor:
- Tên của destructor giống với tên lớp, nhưng được đặt trước bởi ký hiệu dấu ngã (
~
). - Không thể khai báo nhiều hơn một destructor trong một lớp.
- Destructor là cách duy nhất để phá hủy đối tượng đã được tạo ra bởi constructor (hàm khởi tạo), do đó không thể nạp chồng destructor.
- Destructor không thể được khai báo là
static
(tĩnh) hoặcconst
(hằng). - Destructor không nhận tham số và cũng không trả về giá trị nào.
- Destructor được tự động gọi khi một đối tượng ra khỏi phạm vi hoạt động.
- Destructor giải phóng bộ nhớ mà đối tượng đã chiếm dụng khi được tạo ra bởi constructor.
- Khi hủy, các đối tượng sẽ bị phá hủy theo thứ tự ngược lại với thứ tự tạo ra.

Khi nào hàm destructor được gọi?
Hàm destructor sẽ được tự động gọi trong các trường hợp sau:
- Khi một hàm kết thúc.
- Khi chương trình kết thúc.
- Khi một khối lệnh chứa biến cục bộ kết thúc.
- Khi toán tử
delete
được gọi để xóa đối tượng.
Các ngôn ngữ không có Destructor
C
Ngôn ngữ C không có destructor vì đây là một ngôn ngữ lập trình theo hướng thủ tục, không hỗ trợ lập trình hướng đối tượng. Trong C, việc quản lý tài nguyên được thực hiện thủ công thông qua các hàm như malloc()
để cấp phát bộ nhớ và free()
để giải phóng bộ nhớ.
JavaScript
JavaScript không có destructor vì ngôn ngữ này dựa vào cơ chế thu gom rác tự động. Trình thông dịch sẽ tự động giải phóng bộ nhớ khi các đối tượng không còn được sử dụng. Việc quản lý tài nguyên được thực hiện thông qua các mẫu thiết kế như try...finally
hoặc sử dụng các trình lắng nghe sự kiện (event listeners).
Java
Java không có destructor theo nghĩa truyền thống. Thay vào đó, Java sử dụng cơ chế thu gom rác để quản lý bộ nhớ. Trước đây, phương thức finalize()
từng được sử dụng để dọn dẹp tài nguyên, nhưng hiện tại phương pháp này đã bị loại bỏ. Trong Java hiện đại, việc quản lý tài nguyên được thực hiện thông qua cấu trúc try-with-resources
và giao diện AutoCloseable
.
So sánh hàm Destructor với Constructor trong lập trình
Trong lập trình hướng đối tượng C++, Constructor và Destructor là hai khái niệm song hành, đại diện cho hai mốc quan trọng nhất trong vòng đời của một đối tượng. Chúng có mối liên hệ chặt chẽ nhưng lại thực hiện những nhiệm vụ hoàn toàn đối lập nhau trong quá trình quản lý đối tượng.
Việc hiểu rõ điểm giống và khác nhau giữa hai loại hàm đặc biệt này là nền tảng quan trọng. Nó giúp bạn kiểm soát chặt chẽ quá trình tạo lập và dọn dẹp các đối tượng, từ đó viết ra code C++ an toàn và hiệu quả, tránh các lỗi liên quan đến tài nguyên.
Điểm giống nhau giữa Constructor và Destructor
Mặc dù chức năng khác biệt, Constructor và Destructor có vài điểm chung đáng chú ý trong cấu trúc của một class. Cả hai đều là những ‘hàm thành viên đặc biệt’, được thiết kế với vai trò cụ thể và không giống các phương thức thông thường bạn tự định nghĩa trong class.
Điểm giống nhau về cú pháp là cả hai đều mang tên trùng với tên của class chứa chúng. Ví dụ, class MyClass sẽ có Constructor là MyClass() và Destructor là ~MyClass(). Hơn nữa, cả hai loại hàm này đều không có bất kỳ kiểu dữ liệu trả về nào, kể cả void.

Điểm khác nhau giữa Constructor và Destructor
Sự khác biệt lớn nhất nằm ở mục đích tồn tại. Constructor được sinh ra để ‘xây dựng’, thiết lập trạng thái ban đầu cho đối tượng khi nó vừa được tạo ra. Nó chịu trách nhiệm khởi tạo các biến thành viên, cấp phát bộ nhớ hoặc tài nguyên cần thiết cho đối tượng hoạt động.
Ngược lại hoàn toàn, Destructor có nhiệm vụ ‘phá hủy’ một cách có trật tự. Nó được gọi khi đối tượng không còn cần thiết, chịu trách nhiệm giải phóng mọi tài nguyên mà đối tượng đã nắm giữ, đặc biệt là bộ nhớ động đã cấp phát trên Heap để tránh rò rỉ.
Thời điểm được gọi cũng khác biệt rõ rệt. Constructor được kích hoạt khi đối tượng được tạo (qua toán tử new, khai báo trên stack, đối tượng toàn cục…). Destructor thì được gọi khi đối tượng bị hủy (ra khỏi phạm vi scope, dùng toán tử delete, kết thúc chương trình, do ngoại lệ…).
Về cấu trúc, Constructor có thể nhận các tham số đầu vào. Điều này cho phép bạn định nghĩa nhiều Constructor khác nhau (nạp chồng – overload) với các danh sách tham số khác nhau để cung cấp nhiều cách khởi tạo đối tượng linh hoạt.
Destructor thì không bao giờ nhận bất kỳ tham số nào. Điều này cũng có nghĩa là bạn không thể nạp chồng Destructor; một class chỉ có thể có một Destructor duy nhất mà thôi, không phụ thuộc vào tham số vì nó không có.
Một điểm khác biệt quan trọng trong bối cảnh kế thừa và đa hình là khả năng là virtual. Constructor không thể là virtual, nhưng Destructor có thể (và thường nên) là virtual trong các lớp cơ sở để đảm bảo quá trình giải phóng bộ nhớ đúng đắn khi làm việc với con trỏ lớp cha trỏ đến đối tượng lớp con.
Bảng so sánh giữa Constructor và Destructor:
Thuộc tính | Constructor (Hàm khởi tạo) | Destructor (Hàm hủy) |
---|---|---|
Đặc điểm | Khởi tạo trạng thái ban đầu cho đối tượng. | Giải phóng tài nguyên khi đối tượng bị hủy. |
Mục đích | Khởi tạo trạng thái ban đầu cho đối tượng. | Giải phóng tài nguyên khi đối tượng bị hủy. |
Tên | Giống tên lớp | Giống tên lớp, có dấu ~ phía trước. |
Kiểu trả về | Không có | Không có (cả void). |
Tham số | Có thể có (cho phép nạp chồng) | Không có bất kỳ tham số nào. |
Số lượng | Có thể có nhiều (nạp chồng) | Chỉ có một duy nhất. |
Khi được gọi | Khi đối tượng được tạo (new hoặc tự động). | Khi vòng đời đối tượng kết thúc (delete hoặc tự động). |
Từ khóa new | Được gọi sau new (trên heap). | Được gọi trước khi bộ nhớ được giải phóng bởi delete (trên heap). |
Tóm lại, Destructor (Hàm hủy) là một khái niệm cốt lõi trong C++ mà mọi lập trình viên đều cần nắm vững. Nó là cơ chế tự động giúp giải phóng tài nguyên đã được cấp phát bởi đối tượng trong suốt vòng đời của nó, ngăn chặn hiệu quả tình trạng rò rỉ bộ nhớ và các tài nguyên khác.
Việc hiểu rõ Hàm hủy là gì, cách hoạt động, cùng những đặc điểm và sự khác biệt với Constructor, chính là chìa khóa để bạn viết code C++ an toàn, hiệu quả và chuyên nghiệp hơn, làm chủ hoàn toàn vòng đời của đối tượng trong ứng dụng của mình.
Khi đã thành thạo việc quản lý tài nguyên với Destructor trong C++, bước tiếp theo là đưa ứng dụng của bạn vào hoạt động thực tế. Destructor và quản lý bộ nhớ (qua new/delete, RAII) là CỰC KỲ quan trọng đối với các ứng dụng C++ chạy trên server. Điều này đòi hỏi một nền tảng máy chủ ổn định, đủ mạnh để code C++ hiệu suất cao của bạn có thể vận hành trơn tru. InterData cung cấp các giải pháp như thuê Hosting giá rẻ tốc độ cao chỉ 1K/ngày và thuê VPS chất lượng giá rẻ, sẵn sàng hỗ trợ ứng dụng của bạn.
Ngoài ra, bạn có thể khám phá dịch vụ thuê Cloud Server giá rẻ tốc độ cao tại InterData. Với phần cứng thế hệ mới, sử dụng CPU AMD EPYC hoặc Intel Xeon Platinum cùng SSD NVMe U.2 siêu tốc, nền tảng này mang lại cấu hình mạnh mẽ, dung lượng được tối ưu và băng thông cao. Đây là môi trường lý tưởng cho ứng dụng C++ của bạn hoạt động ổn định trên hạ tầng uy tín, cao cấp.
INTERDATA
- Website: Interdata.vn
- Hotline: 1900-636822
- Email: [email protected]
- VPĐD: 240 Nguyễn Đình Chính, P.11. Q. Phú Nhuận, TP. Hồ Chí Minh
- VPGD: Số 211 Đường số 5, KĐT Lakeview City, P. An Phú, TP. Thủ Đức, TP. Hồ Chí Minh