2011-01-12 32 views
29

Tôi có một con trỏ tới một đối tượng. Tôi muốn lưu trữ nó trong hai container mà cả hai đều có quyền sở hữu. Vì vậy, tôi nghĩ rằng tôi sẽ là tốt để làm cho nó một shared_ptr của C + + 0x. Làm thế nào tôi có thể chuyển đổi một con trỏ thô thành một shared_pointer?Tạo shared_ptr từ con trỏ thô

typedef unordered_map<string, shared_ptr<classA>>MAP1; 
MAP1 map1; 
classA* obj = new classA(); 
map1[ID] = how could I store obj in map1?? 

Cảm ơn

Trả lời

28

Bạn cần phải chắc chắn rằng bạn không khởi tạo cả hai đối tượng shared_ptr với con trỏ liệu giống nhau, hoặc nó sẽ bị xóa hai lần. A (nhưng vẫn xấu) cách tốt hơn để làm điều đó:

classA* raw_ptr = new classA; 
shared_ptr<classA> my_ptr(raw_ptr); 

// or shared_ptr<classA> my_ptr = raw_ptr; 

// ... 

shared_ptr<classA> other_ptr(my_ptr); 
// or shared_ptr<classA> other_ptr = my_ptr; 
// WRONG: shared_ptr<classA> other_ptr(raw_ptr); 
// ALSO WRONG: shared_ptr<classA> other_ptr = raw_ptr; 

CẢNH BÁO: mã trên cho thấy thực tế xấu! raw_ptr đơn giản không nên tồn tại dưới dạng biến. Nếu bạn trực tiếp khởi tạo con trỏ thông minh của bạn với kết quả của new, bạn giảm nguy cơ vô tình khởi tạo các con trỏ thông minh khác một cách không chính xác. Những gì bạn nên làm là:

shared_ptr<classA> my_ptr(new classA); 

shared_ptr<classA> other_ptr(my_ptr); 

Điều tốt đẹp là mã này ngắn gọn hơn.

EDIT

tôi có lẽ nên xây dựng trên nó như thế nào sẽ làm việc với một bản đồ. Nếu bạn có một con trỏ thô và hai bản đồ, bạn có thể làm một cái gì đó tương tự như những gì tôi đã trình bày ở trên.

unordered_map<string, shared_ptr<classA> > my_map; 
unordered_map<string, shared_ptr<classA> > that_guys_map; 

shared_ptr<classA> my_ptr(new classA); 

my_map.insert(make_pair("oi", my_ptr)); 
that_guys_map.insert(make_pair("oi", my_ptr)); 
// or my_map["oi"].reset(my_ptr); 
// or my_map["oi"] = my_ptr; 
// so many choices! 
+2

Không hiển thị con trỏ thô trong biến. Bằng cách đó, bạn cung cấp cho một người duy trì một cơ hội dễ dàng hơn để vít lên và đưa con trỏ RAW vào một con trỏ được chia sẻ khác. Chỉ cần sử dụng 'my_ptr (new ClassA());' Bằng cách đó, người duy trì phải làm thêm công việc để vặn mọi thứ. –

+0

@Martin York Tôi chỉ chỉnh sửa để bao gồm một điểm về điều đó; Tôi sẽ thêm một lưu ý rõ ràng hơn. Nhưng bạn là chính xác. :) – Dawson

+0

'// hoặc shared_ptr my_ptr = raw_ptr;' sai trong 'std :: shared_ptr', vì nó phải rõ ràng là' // hoặc shared_ptr my_ptr (raw_ptr); '. – Justme0

3

Bạn có thể sử dụng nhiều cách khác nhau, nhưng thiết lập lại() sẽ là tốt:

map1[ID].reset(obj); 

Và để giải quyết vấn đề có hai bản đồ tham khảo các shared_ptr cùng, chúng ta có thể có:

map2[ID] = map1[ID]; 

Lưu ý rằng mẹo nói chung để tránh xóa kép là cố gắng tránh con trỏ thô. Do đó tránh:

classA* obj = new classA(); 
map1[ID].reset(obj); 

nhưng thay vì đưa các đối tượng đống mới thẳng vào một shared_ptr.

+0

nó không phải là thực hành xấu cho mỗi se, đó là c-thực hành! – g24l

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