[Smart Pointers] std::unique_ptr trong C++

std::unique_ptr là gì ?

std::unique_ptr là một trong số các Smart Pointers của C++, được support từ C++11, định nghĩa trong file header <memory>. std::unique_ptr là một class template (khuôn mẫu lớp) dùng để quản lý lifetime của dynamic object (đối tượng được cấp phát động trong runtime) chứa trong nó. Đối tượng chứa trong một std::unique_ptr thì chỉ thuộc sở hữu của std::unique_ptr đó mà thôi. Cũng như các Smart Pointers khác của C++, khi sử dụng std::unique_ptr chúng ta không cần phải lo về việc giải phóng vùng nhớ của dynamic object vì khi một biến std::unique_ptr đi ra khỏi phạm vi của nó thì đối tượng mà nó sở hữu cũng sẽ bị xoá, trong trường hợp đối tượng là instance của một class thì hàm huỷ của class đó sẽ được gọi và vùng nhớ dành cho đối tượng đó sẽ được giải phóng.

Sử dụng std::unique_ptr như thế nào ?

*** Đoạn code trong ví dụ sau sẽ thực hiện cấp phát động một đối tượng của class Test và trao quyền sở hữu đối tượng đó cho ptr (tức là biến ptr sẽ chứa con trỏ trỏ tới vùng nhớ của đối tượng này) →

Khi hàm main() kết thúc, biến ptr sẽ bị huỷ và đối tượng của class Test thuộc quyền sở hữu của ptr cũng sẽ được huỷ một cách tự động. Chương trình này sẽ output ra màn hình như sau →

*** Tiếp ví dụ trên, nếu muốn chuyển quyền sở hữu dynamic object từ một std::unique_ptr sang một std::unique_ptr khác thì cần sử dụng câu lệnh std::move, khi đó unique_ptr gốc sẽ trỏ tới nullptr. Ví dụ →

Chương trình sau này vẫn cho ra output như cũ.

Chú ý: std::make_unique có từ C++14. Ở C++11 thì dùng std::unique_ptr kết hợp với toán tử new như sau →

*** Bạn có thể truy cập và sử dụng std::unique_ptr giống như con trỏ thông thường vì nó đã overload các toán tử *->. Ví dụ →

Chương trình này sẽ output ra như sau →

*** Cũng có thể sử dụng std::unique_ptr để quản lý 1 array các dynamic objects. Ví dụ →

arr_ptr sẽ sở hữu một mảng 10 phần tử kiểu int được cấp phát động, chúng ta có thể truy cập đến các phần tử của mảng này thông qua biến arr_ptr như một mảng bình thường. Khi biến arr_ptr ra khỏi phạm vi khai báo của nó, nó sẽ bị xoá và kéo array được cấp phát động mà nó sở hữu cũng được tự động giải phóng theo, không lo bị leak memory.

Xem thêm

— Phạm Minh Tuấn (Shun) —