2008-10-07 69 views
24

Tôi nhớ đọc ở đâu đó rằng việc sử dụng các tham chiếu đến con trỏ thông minh có thể gây ra tham nhũng bộ nhớ. Điều này đơn giản chỉ vì sử dụng tham chiếu của con trỏ thông minh sau khi nó bị phá hủy? Hay tính toán tham chiếu có bị rối tung lên không?Tại sao bạn không nên sử dụng tham chiếu đến con trỏ thông minh?

Cảm ơn để làm rõ

+0

Đó là lý do tương tự để lưu trữ các tham chiếu đến các loại đối tượng khác là xấu, đối tượng có thể bị phá hủy và bạn sẽ có một tham chiếu lơ lửng. Con trỏ thông minh được cho là để giữ cho đối tượng mà chúng trỏ tới còn sống, nhưng chúng ta không nói về đối tượng được trỏ tới, chúng ta đang nói về chính đối tượng con trỏ thông minh. – bames53

+0

Xem http://stackoverflow.com/questions/327573/c-passing-references-to-boostshared-ptr –

Trả lời

14

Giả sử bạn đang nói về shared_ptr đây ...

này đơn giản chỉ vì sử dụng tài liệu tham khảo của con trỏ thông minh sau là nó bị phá hủy?

Đây là câu trả lời hay. Bạn có thể không biết tuyệt đối tuổi thọ của con trỏ mà tham chiếu của bạn cũng đề cập đến.

Để giải quyết vấn đề này, bạn muốn xem xét tăng :: weak_ptr. Nó không tham gia đếm tham chiếu. Khi bạn cần sử dụng nó, nó cung cấp cho bạn một shared_ptr mà biến mất sau khi bạn thực hiện với nó. Nó cũng sẽ cho bạn biết khi nào tham chiếu đến con trỏ đã được thu thập.

Từ các tài liệu weak_ptr

Mẫu cửa lớp weak_ptr một "yếu tham khảo" đến một đối tượng đó là đã được quản lý bởi một shared_ptr. Để truy cập đối tượng, weak_ptr có thể là được chuyển đổi thành shared_ptr bằng cách sử dụng hàm tạo shared_ptr hoặc khóa chức năng . Khi shared_ptr cuối cùng để các đối tượng sẽ biến mất và đối tượng bị xóa, các nỗ lực nhằm có được một shared_ptr từ weak_ptr trường mà tham khảo các xóa đối tượng sẽ thất bại: các nhà xây dựng sẽ ném một ngoại lệ kiểu tăng :: bad_weak_ptr và weak_ptr :: khóa sẽ trả về một số trống rỗng shared_ptr.

Lưu ý rằng phương thức hết hạn() cũng sẽ cho bạn biết nếu ptr của bạn vẫn còn.

5

Khi sử dụng con trỏ thông minh (hoặc bất kỳ đối tượng quản lý phân bổ) nào bạn đang tính vào hành vi được xác định trong hàm tạo/hủy để quản lý refs/derefs/locks/unlocks. Kết quả là, các loại đối tượng đó phải là đối tượng thực sự để thực hiện đúng. khi sử dụng các tham chiếu đến các đối tượng như vậy (hoặc con trỏ), bạn đang bỏ qua cơ chế (và yêu cầu một wedgie).

3

Vẫn còn nhiều trường hợp trong đó tham chiếu tới con trỏ thông minh là một ý tưởng hay. Một ví dụ rõ ràng là phương pháp gán của lớp con trỏ thông minh, chấp nhận tham chiếu đến một con trỏ thông minh khác làm tham số của nó.

Đặt phương thức chấp nhận tham chiếu con trỏ thông minh có nghĩa là tham số không tăng số tham chiếu nội bộ của con trỏ thông minh. Điều này có thể cải thiện hiệu suất - nhưng có lẽ không nhiều. Ngoài ra, có rất nhiều thứ mà phương pháp không thể thực hiện với tham chiếu - hoặc con trỏ thông minh ban đầu. Nếu bạn biết những điều này là gì và tránh chúng, đi qua tham khảo hoạt động tốt. Tất nhiên, mục đích của con trỏ thông minh là tránh phải biết những điều này.

Ngoài ra, nếu bạn có phương pháp sẽ sửa đổi giá trị của thông số con trỏ thông minh, chuyển như tham chiếu là bắt buộc, giống như bất kỳ loại nào khác.

1

Phần "thông minh" của con trỏ thông minh được quản lý bởi các nhà thầu, trình phá hủy, toán tử điều phối và các chức năng khác của lớp con trỏ thông minh. Bằng cách sử dụng một tham chiếu, bạn đang phá vỡ các hoạt động này - hàm tạo sẽ không được gọi khi tham chiếu của bạn được khởi tạo và hàm hủy sẽ không được gọi khi tham chiếu của bạn nằm ngoài phạm vi.

Về bản chất, một tham chiếu đến một con trỏ thông minh là một con trỏ câm, với tất cả các rủi ro và gotchas mà sau này đòi hỏi.

+0

"_với tất cả các rủi ro và gotchas mà sau này đòi hỏi phải có._" đó là? – curiousguy

+0

Điều lớn nhất trong bối cảnh này là thiếu tính tham chiếu. – JohnMcG

0

Chúng tôi đã tùy chỉnh được thực smartpointers và chúng tôi luôn tạo một thói quen đi qua một 'refsomething const &'

nó không tăng hoặc giảm các con trỏ thông minh, và như vậy - và quan trọng hơn - cuộc gọi đến InterLockedIncrement/Giảm được giảm mà lần lượt tránh một memory fence và tất cả những thứ đi với điều đó: khóa xe buýt, bộ nhớ cache, ...

+0

Chức năng "Đã khóa" làm ** không ** gây ra hiệu lực bộ nhớ cache! – curiousguy

+0

Bạn nói đúng. Tôi đã sai. Sẽ không có hiệu lực bộ nhớ cache cũng như khóa bus bộ nhớ trong trường hợp này. Tuy nhiên, nếu có nhiều luồng truy cập vào số lần truy cập này, số chu kỳ bị mất trong các hàm Liên động ... thay vì không xác định và có thể khá cao. Hiệu ứng này thậm chí còn tồi tệ hơn so với bộ nhớ cache. Vì vậy, có những lý do tốt để tránh chúng. – QBziZ

0

Việc chuyển một tham chiếu đến con trỏ thông minh vào một hàm là hoàn toàn an toàn và là một ý tưởng hay. Các đối tượng có thể biến mất nhưng con trỏ thông minh sẽ không, nó sẽ được ngồi ở đó nói null ít nhất cho đến khi hàm trả về. Đó là cách tốt nhất để đánh dấu một con trỏ thông minh trong phạm vi của nó. Nếu bạn sử dụng một tài liệu tham khảo với một sửa đổi lần const vào những gì nó đề cập đến sau đó bạn có một tài liệu tham khảo quan sát thông minh:

const smart_ptr<T>& 

Điều thú vị và hữu ích, const ngăn cản bạn từ việc sử dụng tài liệu tham khảo để nói, null con trỏ thông minh và xóa đối tượng nhưng nó không ngăn con trỏ thông minh ban đầu khỏi tự hủy và tham chiếu của bạn sẽ phản ánh thay đổi đó.

Trả về tham chiếu đến con trỏ thông minh từ một hàm đang yêu cầu tất cả các loại sự cố.

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