Không chỉ khi bạn có nhiều phân bổ, nhưng bất cứ khi nào bạn có thể ném vào các địa điểm khác nhau. Xem xét việc này:
f(make_unique<T>(), function_that_can_throw());
Versus:
f(unique_ptr<T>(new T), function_that_can_throw());
Trong trường hợp thứ hai, trình biên dịch được phép gọi số (theo thứ tự):
new T
function_that_can_throw()
unique_ptr<T>(...)
Rõ ràng nếu function_that_can_throw
thực sự ném thì bạn bị rò rỉ. make_unique
ngăn chặn trường hợp này.
Và tất nhiên, phân bổ thứ hai (như trong câu hỏi của bạn) chỉ là trường hợp đặc biệt là function_that_can_throw()
.
Theo nguyên tắc chung, chỉ cần sử dụng make_unique
để mã của bạn nhất quán. Nó luôn luôn đúng (đọc: ngoại lệ an toàn) khi bạn cần unique_ptr
và không ảnh hưởng đến hiệu suất, vì vậy không có lý do gì để không sử dụng nó (trong khi thực tế không sử dụng nó giới thiệu rất nhiều gotchas).
Câu hỏi của bạn dường như mâu thuẫn với chính nó. Trước tiên, bạn khẳng định rằng nhiều phân bổ là ngoại lệ an toàn, sau đó bạn hiển thị một ví dụ mà điều này có vẻ bề ngoài ngược lại với những gì xảy ra. –
@LightnessRacesinOrbit no, tôi khẳng định rằng nhiều phân bổ không phải là ngoại lệ an toàn. Tôi nói "make_unique chỉ thêm an toàn ngoại lệ khi bạn có nhiều phân bổ trong một biểu thức" có nghĩa là nó không thêm gì cho chỉ một phân bổ. – Kal
Ah! Vâng, được rồi :) –