2012-05-24 39 views
8

Mục tiêu của con trỏ có phạm vi là gì? theo hiểu biết của tôi, con trỏ phạm vi quản lý bộ nhớ trong một khối mã. Nếu tôi muốn khai báo một biến trong một khối, tôi chỉ có thể khai báo nó trên một ngăn xếp và không phải lo lắng về việc làm sạch.Tại sao các con trỏ bị cắt trong tăng

+0

http://www.boost.org/doc/libs/1_36_0/libs/smart_ptr/scoped_ptr.htm#Handle/Body –

Trả lời

1

Vấn đề là bạn có thể tạo và dọn sạch một con trỏ trong phạm vi từ vựng nhất định. Điều này có thể hữu ích trong nhiều tình huống khác nhau và đảm bảo bạn không bị rò rỉ bộ nhớ, bằng cách quên delete nếu bạn sử dụng new một cách rõ ràng, điều này không được khuyến nghị.

Bạn nên lưu ý rằng boost::scoped_ptrphi copyable, và do đó sở hữu nó là tài nguyên hoàn toàn, cho toàn bộ thời gian của nó suốt đời. Điều này cũng làm cho nó an toàn hơn sau đó boost::shared_ptr, vì nó tránh sao chép tài nguyên hoặc vô tình chia sẻ tài nguyên.

{ //Some Scope 

    boost::scoped_ptr<int> i_ptr; 
    // do something with pointer 

} // leave scope, pointer is cleaned up 
4

Không nếu kích thước hoặc loại động. Ngoài ra, con trỏ scoped có thể được đổi chỗ, và trong C++ 11 unique_ptr có thể được di chuyển, do đó, chúng không được sắp xếp đúng.

+1

Trừ rằng "Lý do chính để sử dụng 'scoped_ptr' thay vì' auto_ptr' là để người đọc mã của bạn biết rằng bạn có ý định "bắt đầu tài nguyên là khởi tạo" chỉ được áp dụng cho phạm vi hiện tại và không có ý định chuyển quyền sở hữu "... có vẻ như 'hoán đổi 'không phải là mục đích sử dụng. –

+0

@BenVoigt: Nhưng nó được cung cấp và có thể được sử dụng. – Puppy

+2

Đây là [một chủ đề cũ] (http://lists.boost.org/Archives/boost/2002/09/36359.php) thảo luận tại sao 'swap' trở thành một yêu cầu (về cơ bản vì vậy' scoped_ptr' có thể được sử dụng như một thành viên của một lớp có thể sao chép). –

0

thường là ngăn xếp chuỗi có giới hạn bộ nhớ (xem chuỗi xếp chồng).

đôi khi con trỏ có thể được chuyển cho bạn từ bên ngoài và cần xóa trong phạm vi này (ví dụ: nếu ngoại lệ được ném, mọi cuộc gọi xóa bên dưới dòng đó sẽ không được thực thi). Vì vậy, bạn cần cách nọ cách kia của tự động một cách kỳ diệu dọn dẹp con trỏ

void foo(Object*obj) 
{ 
    //this will ensure that object gets cleaned up even if doFoo() throws an exception 
    boost::scoped_ptr<Object> objCleaner(obj); 
    obj->doFoo(); 
} 
+0

Tôi có thể khai báo con trỏ trên ngăn xếp và nó sẽ tự động được làm sạch khi chức năng hết phạm vi, thành công hoặc thông qua ngoại lệ. Chính xác? – Jimm

+0

{X * x = & someObj; } điều này sẽ không làm cho con trỏ x bị xóa khi nó nằm ngoài phạm vi. someObj sẽ bị xóa khi nó nằm ngoài phạm vi. {X * y = new X();} loại mã này sẽ yêu cầu ptr scoped để tự động xóa – mohaps

2

Không giống như các dữ liệu dựa trên stack, scoped_ptr có thành viên reset() - nói cách khác, bạn có thể xây dựng/hủy nội dung của trái tim của bạn. Với điều này, bạn có thể sử dụng một con trỏ null (kỹ thuật operator unspecified-bool-type) như một lá cờ cho biết có hay không có một đối tượng được xây dựng tại bất kỳ thời điểm nào. Nó cũng cho phép bạn sắp xếp trình tự/hủy diệt độc lập khỏi phạm vi biến nếu cần.

Ngoài ra, hãy xem xét rằng bạn có thể khai báo một scoped_ptr là một thành viên lớp, không chỉ là một biến ngăn xếp. Các docs đề nghị sử dụng scoped_ptr để thực hiện các thành phần xử lý/cơ thể (để ẩn các chi tiết thực hiện của lớp).

Cuối cùng, để xây dựng trên điểm DeadMG của "Không nếu đó là loại động", bạn có thể sử dụng scoped_ptr để thực hiện một hoạt động polymorphic:

{ 
scoped_ptr<Base> a(mode ? new DerivedA : new DerivedB); 
a->polymorphic_function(); 
} 

Nó không thực sự có thể làm điều này với đơn giản stack- phân bổ dựa trên.


Xem thêm ở đây: C++0x unique_ptr replaces scoped_ptr taking ownership?

+0

'boost :: variant '. :) – GManNickG

+0

@GManNickG: Tôi không nghĩ rằng tăng :: biến thể cung cấp một sự thay thế tốt cho đa hình thông qua scoped_ptr - thú vị mặc dù. Cảm ơn! – nobar

+0

Tại sao bạn không nghĩ vậy? – GManNickG

Các vấn đề liên quan