2012-03-29 34 views
5

Tôi đang sử dụng libev yêu cầu truyền dữ liệu của tôi tới khoảng trống * để tuân thủ các cấu trúc được xác định trước của chúng. Tôi cần phải cast boost :: shared_ptr vào một void * và sau đó cast void * trở lại một boost :: shared_ptr. Đây là mã của tôi để làm điều đóboost shared_ptr casting thành void *

void foo(boost::shared_ptr<string>& a_string) 
{ 
void* data = (void*)a_string.get(); 
boost::shared_ptr<string> myString((string*)data); 
} 

Tôi khá chắc chắn việc này tốt, tuy nhiên cách mã của tôi là thiết lập Tôi tin rằng tất cả các tài liệu tham khảo shared_ptr chuỗi của tôi đang đi ra khỏi phạm vi là phương pháp đúc này không làm tăng use_count và do đó shared_ptr là giải phóng bộ nhớ trong khi tôi vẫn cần nó.

Có cách nào để tăng/giảm số lần sử dụng bằng tay không? Lý tưởng nhất là tôi sẽ tăng giá trị use_count khi tôi truyền vào khoảng trống *, vượt qua khoảng trống * của tôi với một hàm khác, bỏ khoảng trống * trở lại shared_ptr và giảm giá trị use_count.

Hoặc nếu có ai biết giải pháp khác cho vấn đề này, tôi có thể sử dụng bất kỳ trợ giúp nào.

+1

Bạn có thể lưu người quan sát trong một lớp chứa cả người quan sát và 'shared_ptr'. Điều này sẽ đảm bảo rằng thời gian tồn tại của người theo dõi sẽ được so khớp hoặc vượt quá tuổi thọ của đối tượng thuộc sở hữu của 'shared_ptr'. Ngoài ra, tại sao không lưu địa chỉ của 'shared_ptr' chính nó thay vì lưu trữ địa chỉ của đối tượng được trỏ tới? – Mankarse

+0

Tôi tìm thấy một hack xung quanh bằng cách làm cho một cấu trúc có chứa shared_ptr và đúc cấu trúc để một void *. Không chắc tôi cảm thấy thế nào về giải pháp này.Ngoài ra, tôi thấy trong một diễn đàn ở đâu đó mà bạn không nên sử dụng địa chỉ của shared_ptr. –

+0

@ user1229962: Bạn đang truyền cái gì 'void *' đến? –

Trả lời

4

Cách thực sự duy nhất để thực hiện việc này là phân bổ một địa chỉ shared_ptr ở đâu đó đủ để sống đủ lâu rồi đặt void* để trỏ đến điều đó.

0

Thử weak_ptr:

shared_ptr<int> p(new int(5)); 
weak_ptr<int> q(p); 

Edit: Xin lỗi tôi đã không đọc những câu hỏi đúng; bạn có thể thử để giữ nó trong phạm vi vì vậy nó không được dọn dẹp

Cập nhật: Một con trỏ yếu có thể thực sự có tác dụng nếu bạn tham khảo các biến sau cuộc gọi của bạn bởi vì sau đó trình biên dịch không thể tối ưu hóa sự tàn phá của a_string shared_ptr (do đó ngăn chặn decr refcount để zero -> phát hành) trước khi bạn tận dụng các con trỏ cơ bản

vì vậy bạn có thể làm điều này:

void foo(boost::shared_ptr<string>& a_string) 
{ 
void* data = (void*)a_string.get(); 
boost::shared_ptr<string> myString((string*)data); 
weak_ptr<string> temp(a_string); // prevent destruction before above line 
// or reference a_string in any meaningless way that CANT be optimised out 
// pre-emptively by the compiler 
} 

a_string vẫn có thể cần phải tham khảo ở đâu đó bên ngoài foo d hiển thị trên ngữ cảnh và những gì bạn đang làm với con trỏ trống (và nếu nó tạo bản sao mới hoặc hoạt động trên dữ liệu trống)

+1

Một weak_ptr không tăng use_count để bộ nhớ vẫn sẽ được giải phóng. Làm thế nào một weak_ptr sẽ giúp đỡ? –

+1

đã cập nhật câu trả lời của tôi. –

1

Nếu bạn tạo void* trở lại boost::shared_ptr, nó sẽ là một con trỏ được chia sẻ mới, không được liên kết với bất kỳ con trỏ được chia sẻ nào khác cũng trỏ đến bộ nhớ được chỉ bởi biến số `void*.

Điều tôi nghĩ bạn cần làm là thêm hỗ trợ enabled_shared_from_this vào các lớp bạn đang nghĩ đến việc sử dụng với shared_ptrs với mã đó.

Điều này cho phép bạn nhận shared_ptr sẽ chia sẻ quyền sở hữu với shared_ptrs hiện có thông qua chức năng thành viên (shared_from_this) trên lớp học của bạn.

Xem boost enabled_shared_from_this docs để biết thêm chi tiết.

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