Hàm hủy (Destructor) trong class C++ | Laptrinhcanban.com

Hàm hủy (Destructor) trong class C++

Cùm tìm hiểu về hàm hủy (Destructor) trong class C++ . Bạn sẽ biết khái niệm hàm hủy (Destructor) trong C++ là gì, cách khai báo cũng như cách sử dụng Destructor trong C++ sau bài học này.

Hàm hủy (Destructor) trong class C++ là gì

Hàm hủy trong class C++ hay còn gọi là Destructor trong C++ là các hàm thành viên được tự động được thực thi khi chương trình hủy một đối tượng (instance) được tạo ra từ class, và được sử dụng với mục đích xóa và giải phóng đối tượng đó khỏi bộ nhớ.

Hàm hủy trong c++ có 3 tính chất như sau:

  • Tên hàm hủy giống tên của class nhưng phải đặt kèm toán tử ~ đằng trước thành ~classname.
  • Hàm hủy không mang kiểu dữ liệu trong nó, cũng như không sử dụng void khi khai báo nó.
  • Hàm hủy không có tham số, cũng không trả về giá trị từ nó.

Nhiệm vụ chính của hàm hủy là giải phóng vùng bộ nhớ đã được sử dụng để lưu đối tượng sau khi nó bị hủy.

Tuy nhiên đối với các kiểu dữ liệu thuộc loại POD như int, double hay kiểu vector thì do chúng có cơ chế tự động giải phóng bộ nhớ nên chúng ta không cần dùng hàm hủy đối với các loại dữ liệu này.

Còn đối với các loại dữ liệu như mảng chẳng hạn vốn không có cơ chế trên, nên sau khi hủy đối tượng thì bắt buộc chúng ta cần phải dùng hàm hủy (Destructor) trong class C++ để giải phóng bộ nhớ đã dùng để lưu giữ chúng.

Trong trường hợp chúng ta không khai báo hàm hủy trong class, chương trình sẽ tự động tạo ra một hàm hủy trống (không có chứa xử lý) và cũng tự động được thực thi khi một đối tượng tạo ra từ class bị xóa khỏi chương trình.

Khai báo hàm hủy trong C++

Cú pháp khai báo hàm hủy trong C++ như sau:

class MyClass {
public:
MyClass(); // Hàm khởi tạo
~MyClass(); // Hàm hủy
};

Trong đó MyClass là tên class, và ~MyClass với sự kết hợp của toán tử ~ và tên class chính là tên của hàm hủy.

Các xử lý trong hàm sẽ được viết kết hợp với toán tử delete bên trong khối của hàm hủy.

Ví dụ cụ thể, chúng ta tạo ra một hàm hủy trong class C++ để giải phóng bộ nhớ đã dùng để lưu mảng như sau:

#include <iostream>  
using namespace std;

/*Khai báo class*/
class MyClass {
private:
char *m_data;

public:
MyClass() // Hàm khởi tạo
{
m_data = new char[100]; //Vùng bộ nhớ được tạo ra để lưu mảng
}
~MyClass() // Hàm hủy
{
delete [] m_data; //Giải phóng vùng bộ nhớ
cout << "Ham huy duoc goi" << endl;
}
};

/*Bắt đầu hàm main*/
int main()
{
MyClass arr1;
//Ham huy duoc goi
}

Giống như trên, khi tạo ra một đối tượng từ class thì biến thành viên m_data sẽ được hàm khởi tạo khai báo giá trị bạn đầu là một mảng 100 phần tử. Để lưu giữ mảng này thì một vùng bộ nhớ sẽ được tự động sử dụng.

Và sau khi đối tượng được tạo ra bị xóa khỏi chương trình, hàm hủy sẽ được tự động thực thi. Khi đó toán tử delete trong hàm sẽ xóa và giải phóng vùng bộ nhớ đã dùng để lưu biến thành viên ban đầu, và dòng “Ham huy duoc goi” cũng được in ra màn hình.

Toán tử delete và cách gọi hàm hủy trong C++

Toán tử delete trong C++ là một toán tử có tác dụng xóa và giải phóng vùng bộ nhớ đã sử dụng để lưu giữ một đối tượng, sau khi đối tượng đó bị xóa khỏi chương trình.

Toán tử delete sẽ có tác dụng ngược hoàn toàn với toán tử new mà chúng ta đã học trong bài Class trong C++. Toán tử new sẽ tạo ra instance từ class, còn toán tử delete sẽ xóa và giải phóng bộ nhớ đã dùng để lưu instance đó.

Nói cách khác thì toán tử delete cũng có tác dụng gọi hàm hủy trong class C++. Tuy nhiên có một điểm đặc biệt là chúng ta có thể sử dụng toán tử delete bên trong hàm hủy (trong class), hoặc là sử dụng nó độc lập bên ngoài class cũng được.

Hãy cùng nhớ lại trong bài Class trong C++ chúng ta đã biết có 2 cách để tạo ra instance từ class, đó là sử dụng toán tử new và không sử dụng toán tử new.

Và tương ứng với 2 cách trên mà chúng ta cũng cần sử dụng toán tử delete để gọi hàm hủy trong C++ một cách tương ứng. Quy tắc ở đây là:

  1. Nếu tạo instance từ class mà không dùng toán tử new, thì hàm hủy trong class sẽ tự động được gọi và giải phóng bộ nhớ sau khi kết thúc phiên làm việc với instance đó. Nói cách khác thì instance sẽ tồn tại cho tới khi kết thúc phiên làm việc với nó.

  2. Nếu tạo instance từ class mà dùng toán tử new, thì hàm hủy trong class sẽ không tự động được gọi, mà phải chờ cho tới khi toán tử delete xuất hiện. Nói cách khác thì instance sẽ tồn tại ngay cả sau khi đã kết thúc phiên làm việc với nó, cho tới khi toán tử delete được gọi.

Ví dụ chúng ta có class sau đây:

#include <iostream>  
using namespace std;

class MyClass {
private:
char *m_data;

public:
MyClass() // Hàm khởi tạo
{
m_data = new char[100]; //Vùng bộ nhớ được tạo ra để lưu mảng
}
~MyClass() // Hàm hủy
{
delete [] m_data; //Giải phóng vùng bộ nhớ
cout << "Ham huy duoc goi" << endl;
}
};

Hãy so sánh kết quả khi có và không sử dụng toán tử new khi tạo instacne từ class như sau:

int main()
{
MyClass arr1;
// "Ham huy duoc goi"

MyClass *arr2 = new MyClass();
// hàm hủy không được gọi, nên ko có gì xảy ra
}

Có thể thấy rõ ở lần tạo instance thứ nhất không dùng toán tử new, nên hàm hủy được tự động gọi, và dòng “Ham huy duoc goi” được in ra.

Tuy nhiên ở lần tạo instance thứ hai, do dùng toán tử new dẫn đến hàm hủy không được tự động gọi, nên không có gì in ra màn hình cả.

Bây giờ, hãy xem khi chúng ta thêm toán tử delete thì điều gì xảy ra:

int main()
{
MyClass arr1;
// "Ham huy duoc goi"

MyClass *arr2 = new MyClass();
// hàm hủy không được gọi, nên ko có gì xảy ra

delete arr2;
// "Ham huy duoc goi"
}

Do toán tử delete đã gọi hàm hủy, nên kết quả dòng “Ham huy duoc goi” đã được in ra màn hình.

Tổng kết

Trên đây Kiyoshi đã hướng dẫn bạn về hàm hủy trong C++ rồi. Để nắm rõ nội dung bài học hơn, bạn hãy thực hành viết lại các ví dụ của ngày hôm nay nhé.

Và hãy cùng tìm hiểu những kiến thức sâu hơn về C++ trong các bài học tiếp theo.

Hãy chia sẻ và cùng lan tỏa kiến thức lập trình Nhật Bản tại Việt Nam!

HOME>> >>

Profile
きよしです!笑

Tác giả : Kiyoshi (Chis Thanh)

Kiyoshi là một cựu du học sinh tại Nhật Bản. Sau khi tốt nghiệp đại học Toyama năm 2017, Kiyoshi hiện đang làm BrSE tại Tokyo, Nhật Bản.