2012-11-13 24 views
6

Tôi không chắc liệu mình có phải chịu đựng nhiều hơn từ lỗi tài liệu hay đau đầu hay không, vì vậy ...Làm cách nào để tạo một shared_ptr cho một thành viên?

Điều tôi muốn làm là tạo shared_ptr chia sẻ quyền sở hữu với người khác, nhưng tham chiếu đến thành viên đối tượng thay vì toàn bộ đối tượng. ví dụ đơn giản, điểm khởi đầu ...

struct s 
{ 
    int a, b; 
}; 

shared_ptr<s> s1 (new s); // pointing to whole object 

Từ en.cppreference.com, nhà xây dựng (8) của shared_ptr là ...

template< class Y > 
shared_ptr(const shared_ptr<Y>& r, T *ptr); 

Mô tả đề cập đến "xây dựng một shared_ptr mà chia sẻ thông tin sở hữu với r, nhưng giữ một ptr trỏ không liên quan và không được quản lý ... chẳng hạn như trong các trường hợp sử dụng điển hình trong đó ptr là một thành viên của đối tượng được quản lý bởi r ".

Vì vậy, ... Đã T chỉ vô tình bị bỏ lỡ từ mẫu trong hàm tạo đó, hoặc tôi có thiếu gì đó không? Trong thực tế, Y có vẻ như nó sai với tôi quá, vì vậy chỉ cần nói chung là constructor mô tả chính xác?

Những gì tôi đang hy vọng tôi có thể làm là một cái gì đó như thế này ...

shared_ptr<int> s2 (s1, &(s1.get()->a)); 

s2 điểm thành viên a (một int), nhưng sở hữu cổ phần của toàn bộ đối tượng với s1.

Đó có phải là lành mạnh không?

+0

Có lẽ tôi đang thiếu một cái gì đó, nhưng tại sao bạn sẽ muốn có một shared_ptr đến một var thành viên đó không được phân bổ trên heap? tức là tại sao không chỉ sử dụng một con trỏ thô cho s2? –

+0

@RC - để đảm bảo rằng nếu shared_ptr ban đầu được deallocated, đối tượng chính nó không - tức là để đảm bảo rằng s2 không trở thành một con trỏ lơ lửng. Trong một ví dụ thế giới thực, phạm vi của s1 và s2 sẽ không giống nhau. – Steve314

+0

Vâng, nó hoàn toàn lành mạnh. Ngoài ra, bạn không cần một '.get()'. – atzz

Trả lời

9

Thông số T là tham số mẫu trên chính mình là shared_ptr, trong khi thông số Y là thông số mẫu trên hàm tạo shared_ptr cụ thể đó. Một cái gì đó như thế này:

template< class T > 
class shared_ptr 
{ 
    template< class Y > 
    shared_ptr(const shared_ptr<Y>& r, T *ptr); 
} 

Đối với mã ví dụ bạn đã đăng, có vẻ ổn với tôi.

+0

Quyền của mọi người - bạn sẽ giành chiến thắng nhanh hơn một chút. Tôi cảm thấy một chút ngu ngốc - tôi rõ ràng đã không làm nhiều thứ mẫu gần đây. Tôi hoàn toàn quên mất các mẫu thành viên. – Steve314

4

Tài liệu là chính xác. Cậu quên rằng đây là tài liệu của một nhà xây dựng trên lớp mẫu shared_ptr<T> ví dụ: khai báo lớp trình độ của các nhà xây dựng là:

template<typename T> 
template<typename Y> 
shared_ptr<T>::shared_ptr(const shared_ptr<Y>& r, T *ptr); 

Vì vậy, trong ví dụ của bạn TintYs.

2

T là thông số mẫu của lớp, không phải của hàm tạo. Và điều này là chính xác như nó cần phải là: Một con trỏ đến một thành viên phải có loại của thành viên và quên/xóa (xem loại tẩy xóa) loại đối tượng có chứa (Y, trong trường hợp này).

Mã bạn gửi nên làm việc, thậm chí bạn có thể viết nó đơn giản hơn một chút như:

shared_ptr<int> s2 (s1, &s1->a); 
+0

Vì một lý do nào đó, tôi không bao giờ chắc chắn về sự ưu tiên của '&' - có lẽ vì tôi luôn bổ sung thêm parens thay vì kiểm tra. 'Get' cũng có chủ ý, nhưng tôi không chắc chắn lý do làm cho mọi thứ trở nên rõ ràng hơn có ý nghĩa hay không. Tôi nên thực sự gắn bó với đổ lỗi cho đau đầu của tôi. – Steve314

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