unique_ptr
không thể sao chép, nó chỉ có thể di chuyển.
Điều này sẽ ảnh hưởng trực tiếp đến Kiểm tra, trong ví dụ thứ hai của bạn, cũng chỉ có thể di chuyển và không thể sao chép.
Trên thực tế, điều tốt là bạn sử dụng unique_ptr
nó sẽ bảo vệ bạn khỏi một sai lầm lớn.
Ví dụ, vấn đề chính với mã đầu tiên của bạn là con trỏ không bao giờ bị xóa, điều này thực sự rất tệ. Giả sử, bạn sẽ sửa lỗi này bằng cách:
class Test
{
int* ptr; // writing this in one line is meh, not sure if even standard C++
Test() : ptr(new int(10)) {}
~Test() {delete ptr;}
};
int main()
{
Test o;
Test t = o;
}
Điều này cũng tệ. Điều gì xảy ra, nếu bạn sao chép Test
? Sẽ có hai lớp có một con trỏ trỏ đến cùng một địa chỉ.
Khi một cái Test
bị phá hủy, nó cũng sẽ phá hủy con trỏ. Khi thứ hai của bạn Test
bị phá hủy, nó cũng sẽ cố gắng xóa bộ nhớ đằng sau con trỏ. Nhưng nó đã bị xóa và chúng tôi sẽ gặp một số lỗi thời gian chạy truy cập bộ nhớ kém (hoặc hành vi không xác định nếu chúng tôi không may mắn).
Vì vậy, cách đúng là triển khai hàm tạo bản sao và toán tử gán sao chép, để hành vi rõ ràng và chúng ta có thể tạo bản sao.
unique_ptr
là con đường phía trước của chúng tôi ở đây. Nó có ý nghĩa ngữ nghĩa: “ Tôi là unique
vậy, vì vậy bạn không thể chỉ sao chép tôi. ” Vì vậy, nó ngăn chúng ta khỏi sai lầm khi thực hiện các toán tử trong tầm tay.
Bạn có thể xác định hàm tạo bản sao và toán tử gán sao chép cho hành vi đặc biệt và mã của bạn sẽ hoạt động. Nhưng bạn, đúng như vậy (!), Buộc phải làm điều đó.
Đạo đức của câu chuyện: luôn sử dụng unique_ptr
trong những tình huống như thế này.