Nội dung bài viết
La Kiến Vinh Để làm rõ hơn về phương thức khởi tạo và phương thức hủy, chỉ cần chỉ rõ hơn về nguồn gốc của nó sẽ giúp cho ta hiểu thấu đáo hơn và dễ sử dụng hơn trong quá trình lập trình, tránh các rủi ro và sự hiểu cứng nhắc trong lập trình với các phương thức này.

Giới thiệu

Trong bài viết này, tôi trình bày về phương thức tạo và phương thức hủy, chủ yếu là đề cập trong ngôn ngữ C++ nhằm làm rõ hơn vấn đề và ý nghĩa của 2 phương thức này vì nó cũng thường gây bối rối cho nhiều lập trình viên. Sự bối rối này đến từ việc chúng ta không phải là cha đẻ của nó, nên chúng ta không hiểu vì sao nó được tạo ra.

Tôi đã trình bày về 2 phương thức này một phần ở bài viết Sự Ra Đời Của Phương Thức Khởi Tạo (Constructor), Phương Thức Hủy (Destructor) Trong Một Class - C++ và đây là phần kết thúc của việc trình bày 2 vấn đề này.

Tiền đề bài viết

Bài viết này xuất phát từ yêu cầu của một độc giả STDIO. Tôi cố gắng hoàn thành bài này nhằm giúp bạn đọc giải quyết được vấn đề này.

Đối tượng hướng đến

Dành cho bạn đọc đã gửi yêu cầu cho chúng tôi và giúp cho các bạn đã có kiến thức về hướng đối tượng vì bài viết chủ yếu làm rõ vấn đề chứ không hướng dẫn kiến thức.

Vấn đề đồng bộ hóa codes giữa các kiểu dữ liệu

Xét ví dụ sau với một biến int primitiveType

void func()
{
	// INIT VARIABLE
	int primitiveType = 0;
	
	// DO SOMETHING
	
	// DONE
}

Biến primitiveType theo lý thuyết được cấp phát khi vào hàm func và được thu hồi khi hàm func thực thi xong. Mọi thứ liên quan đến biến này sẽ được dọn dẹp sạch sẽ trong bộ nhớ.

Đối với một Object, mọi việc phức tạp hơn 1 chút vì bản thân Object sẽ chứa đựng những thuộc tính bên trong nó, một ví dụ điển hình nhất là nếu thuộc tính của Object là một dạng pointer và có xảy ra cấp phát động trong khi pointer này đang quản lý vùng nhớ cấp phát động đó. Vậy, nó phải cần lưu ý thu hồi vùng nhớ đó trước khi Object bị hủy, ta sẽ phải hiện thực thêm phương thức Destroy (phương thức này có nhiệm vụ là delete toàn các pointer đang quản lý các vùng nhớ có cấp phát động) trong class của Object đó và gọi nó trước khi func kết thúc. Ta sẽ có code như sau.

void func()
{
	// INIT VARIABLE
	Object obj = 0;
	
	// DO SOMETHING
	
	// DONE
	obj.Destroy();
}

Vấn đề nảy sinh là, nó có vẻ không đồng bộ nếu ta dùng 1 dạng kiểu dữ liệu cơ bản như ví dụ bên trên int primitiveType khi mà trong code xuất hiện thêm dòng obj.Destroy().

Để đồng bộ được tư tưởng này, tránh gọi thêm các phương thức, kỹ thuật hỗ trợ thêm cho ta khái niệm Destructor và ta chỉ cần hiện thực bên trong đó, khi nào đối tượng sắp bị hủy, thì Destructor sẽ được tự gọi, giúp cho code, nói về tư tưởng đồng bộ hơn.

Giả sử ta đã thiết kế sẵn việc delete các vùng nhớ do các pointer của class Object trong Destructor, lúc này ta chỉ việc Code như 1 dạng kiểu dữ liệu primitive (kiểu dữ liệu dựng sẵn như int, char, ...).

void func()
{
	// INIT VARIABLE
	Object obj = 0;
	
	// DO SOMETHING
	
	// DONE

}

Vậy trong 2 trường hợp là Object và Primitive Type thì codes tương tự nhau.

Lưu ý rằng việc đồng bộ code này cũng tương ứng với Constructor.

THẢO LUẬN
ĐÓNG