Mã này có chính xác không?Liệu unique_ptr :: release() có gọi là destructor không?
auto v = make_unique<int>(12);
v.release(); // is this possible?
Có tương đương với delete
của con trỏ thô không?
Mã này có chính xác không?Liệu unique_ptr :: release() có gọi là destructor không?
auto v = make_unique<int>(12);
v.release(); // is this possible?
Có tương đương với delete
của con trỏ thô không?
Không, mã gây rò rỉ bộ nhớ. release
được sử dụng để phát hành quyền sở hữu của đối tượng quản lý mà không xóa nó:
auto v = make_unique<int>(12); // manages the object
int * raw = v.release(); // pointer to no-longer-managed object
delete raw; // needs manual deletion
Đừng làm điều này trừ khi bạn có lý do chính đáng để sắp xếp nguyên bộ nhớ mà không có một mạng lưới an toàn.
Để xóa đối tượng, hãy sử dụng reset
.
auto v = make_unique<int>(12); // manages the object
v.reset(); // delete the object, leaving v empty
Là một chủ đề hoàn toàn tắt, tôi đã thấy mọi người viết 'int * raw' và' int * raw', nhưng đó là lần đầu tiên tôi thấy 'int * raw' – CoryKramer
@Cyber: Đó là vấn đề về hương vị. Tôi không quan tâm đến vòng loại con trỏ như là "đính kèm" cho một trong hai loại hoặc biến, vì vậy tôi không đính kèm nó vào một trong hai. –
Nếu thấy buồn khi họ quyết định sử dụng các tên hàm này. Một cái gì đó giống như 'tách 'sẽ ít gây hiểu nhầm hơn' giải phóng'. – minexew
release
sẽ làm rò rỉ con trỏ thô của bạn vì bạn không gán cho bất kỳ thứ gì.
Nó có nghĩa là để được sử dụng cho một cái gì đó giống như
int* x = v.release();
Có nghĩa v
không còn quản lý thời gian tồn tại của con trỏ đó, nó được ủy quyền sở hữu con trỏ thô để x
. Nếu bạn chỉ cần release
mà không gán cho bất cứ điều gì, bạn bị rò rỉ con trỏ thô.
Mã này có đúng không?
Không! Nó sẽ bị rò rỉ.
release()
chỉ để mã gọi lại sở hữu bộ nhớ mà unique_ptr
được giữ cho đến khi được gọi. Nếu bạn không gán con trỏ trả về bởi release()
, bạn sẽ bị rò rỉ.
Xóa rõ ràng cho unique_ptr
sẽ là reset()
. Nhưng hãy nhớ rằng unique_ptr
là có để bạn không phải quản lý trực tiếp bộ nhớ mà họ nắm giữ. Tức là, bạn nên biết rằng unique_ptr
sẽ xóa con trỏ thô cơ bản của nó một cách an toàn khi nó nằm ngoài phạm vi.
Vì vậy, bạn nên có lý do rất tốt để thực hiện quản lý bộ nhớ thủ công trên đối tượng quản lý bộ nhớ tự động.
Mã này có chính xác không?
số Sử dụng std::unique_ptr<>::reset()
để xóa các con trỏ liệu nội bộ:
auto v = std::make_unique<int>(12);
v.reset(); // deletes the raw pointer
Sau đó được thực hiện, std::unique_ptr<>::get()
sẽ trở lại nullptr
(trừ khi bạn cung cấp một tham số phi nullptr
-std::unique_ptr<>::reset()
).
nó có thể là một chút khó khăn với nhiều loại tùy ý:
unique_ptr<Foo> v = get_me_some_foo(); // manages the object
Foo * raw = v.release(); // pointer to no-longer-managed object
delete raw;
là gần như chính xác.
unique_ptr<Foo> v = get_me_some_foo(); // manages the object
Foo * ptr = v.release(); // pointer to no-longer-managed object
v.get_deleter() (ptr);
điều này sẽ chính xác trong mọi tình huống; có thể có một deleter tùy chỉnh được định nghĩa trên kiểu Foo, nhưng sử dụng deleter được trả về bởi đối tượng unique_ptr là tốt cho tất cả các trường hợp.
@MikeSeymour Yeah, Cảm ơn! – 0x499602D2