2012-12-25 8 views
6

Tôi đã có một câu hỏi noob đơn giản rằng tôi không thể tìm thấy câu trả lời cho:Chuyển đổi đối tượng để std :: unique_ptr

Trong C++ làm thế nào để bạn chuyển đổi một đối tượng thường xuyên

int i; 

thành một std::unique_ptr?

std::unique_ptr<int> iptr = &i; //invalid 
std::unique_ptr<int> iptr = static_cast<std::unique_ptr<int>>(&i); //invalid 

Cảm ơn.

Trả lời

11

Bạn không. Đối tượng đó không thể bị xóa bởi delete, đó là những gì mà unique_ptr sẽ thực hiện. Bạn cần

auto iptr = make_unique<int>(); 

Ở đây, chúng tôi xác định make_unique là một chức năng tiện ích giống như make_shared, lẽ ra phải là Tiêu chuẩn nhưng rất tiếc là đã bị bỏ qua. Dưới đây là triển khai tóm tắt:

template<typename T, typename... Args> std::unique_ptr<T> make_unique(Args&&... args) { 
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); 
} 
+0

Mặc dù cho đầy đủ chức năng sẽ được tốt đẹp, nhưng tôi không nghĩ rằng nó đã bị bỏ qua rất nhiều là không cần thiết. Hãy nhớ rằng make_shared giải quyết vấn đề phân bổ hai đối tượng cùng một lúc (không có hàm tạo tương đương), trong khi unique_ptr chỉ đơn giản là không cần điều này (nó có không có chi phí bằng thiết kế). –

+0

Điều đó không đúng. Vẫn có một trường hợp ngoại lệ không an toàn nếu bạn xây dựng hai unique_ptrs trong một cuộc gọi hàm, ví dụ, make_unique tiết kiệm. – Puppy

+0

Bạn không thể tránh điều đó bằng cách tạo unique_ptr trực tiếp tại điểm đó? 'func (unique_ptr (T mới), unique_ptr (new U))' –

4

Bạn không. i không được phân bổ động nên không cần xóa. Nếu bạn gói một con trỏ thông minh xung quanh địa chỉ của nó, nó sẽ làm delete &i tại một số điểm và cung cấp cho bạn hành vi không xác định. Bạn chỉ nên quấn một cái gì đó bạn có new ed trong một con trỏ thông minh, như vậy:

std::unique_ptr<int> ptr(new int(5)); 

Toàn bộ vấn đề của một con trỏ thông minh là nó quản lý thời gian tồn tại của một đối tượng được cấp phát động cho bạn. i có thời lượng lưu trữ tự động, do đó sẽ bị hủy ở cuối phạm vi của nó. Bạn không cần bất cứ điều gì để giúp bạn với điều đó.

0

Khi unique_ptr sẽ bị phá hủy những gì sẽ xảy ra? Hoặc cách khác, khi biến được ra khỏi phạm vi? Nó làm cho không có ý nghĩa thực sự

1

Tôi tin rằng điều này sẽ làm việc:

int i; 
auto deleter = [](int *ptr){}; 
std::unique_ptr<int, decltype(deleter)> iptr(&i, deleter); 

Bạn phải cung cấp một deleter tùy chỉnh mà không làm gì. Trình gỡ rối mặc định không thể xóa biến tự động không được phân bổ bởi new. (Tuy nhiên, điều này đánh bại mục đích của việc sử dụng một con trỏ thông minh, nhưng cho thấy rằng nó là có thể).