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) →
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <iostream> #include <string> #include <memory> class Test { private: int mX; public: Test() { std::cout << "Test's constructor" << std::endl;} ~Test() { std::cout << "Test's destructor" << std::endl; } void setX(int x) { mX = x; } int getX() { return mX; } }; int main() { std::unique_ptr<Test> ptr = std::make_unique<Test>(); return 0; } |
1 2 |
Test's constructor Test's destructor |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#include <iostream> #include <string> #include <memory> class Test { private: int mX; public: Test() { std::cout << "Test's constructor" << std::endl;} ~Test() { std::cout << "Test's destructor" << std::endl; } void setX(int x) { mX = x; } int getX() { return mX; } }; int main() { std::unique_ptr<Test> ptr = std::make_unique<Test>(); std::unique_ptr<Test> ptr1 = std::move(ptr); // chuyển quyền sở hữu return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <iostream> #include <string> #include <memory> class Test { private: int mX; public: Test() { std::cout << "Test's constructor" << std::endl;} ~Test() { std::cout << "Test's destructor" << std::endl; } void setX(int x) { mX = x; } int getX() { return mX; } }; int main() { std::unique_ptr<Test> ptr = std::unique_ptr<Test>(new Test()); // or std::unique_ptr<Test> ptr(new Test()); return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include <iostream> #include <string> #include <memory> class Test { private: int mX; public: Test() { std::cout << "Test's constructor" << std::endl;} ~Test() { std::cout << "Test's destructor" << std::endl; } void setX(int x) { mX = x; } int getX() { return mX; } }; int main() { std::unique_ptr<Test> ptr = std::make_unique<Test>(); ptr->setX(10); std::cout << ptr->getX() << std::endl; return 0; } |
1 2 3 |
Test's constructor 10 Test's destructor |
1 2 |
std::unique_ptr<int[]> arr_ptr = std::make_unique<int[]>(10); arr_ptr[2] = 10; // Modify third element |
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) —
