2016-03-31 12 views
6

Có vẻ như các chức năng so sánh volatile trong việc triển khai shared_ptr không tồn tại.Trong C++ - có thể so sánh biến tần shared_ptr với nullptr không?

Thậm chí có tồn tại không?

+5

Lưu ý rằng 'volatile' không phải là một cơ chế đồng bộ hóa chuỗi di động (mặc dù được cho là trong một số môi trường có thể là đủ). le' thường được sử dụng kết hợp với bộ nhớ I/O ánh xạ và các cơ chế tương tự, đó sẽ là một nơi lạ cho 'shared_ptr'. Có lẽ bạn nên làm rõ * tại sao * bạn sẽ có một shared_ptr dễ bay hơi. – peterchen

+3

@peterchen http://cxx.isvolatileusefulwiththreads.com/ –

+0

@MikeVine: Tuyệt vời! Phải nhớ liên kết đó.(Và kiểm tra nó hàng ngày, trong trường hợp nó thay đổi) – peterchen

Trả lời

4

Về cơ bản không, tiêu chuẩn không phục vụ cho comparisons hoặc boolean conversion trên volatile shared_ptr.

Các following fails để biên dịch ...

auto main() -> int { 
    volatile shared_ptr<int> a; 
    if (a == nullptr) // fails 
     ; // empty 
    if (a) // fails 
     ; // empty 
} 

Bạn có thể cast volatile tắt (qua. Một const_cast), nhưng tôi không chắc chắn rằng sẽ có kết quả mong muốn. Từ cppreference:

Sửa đổi một đối tượng const thông qua một con đường phi const truy cập và đề cập đến một đối tượng volatile qua một volatile kết quả phi glvalue trong hành vi undefined.

Về tổng quát hơn, trong không đánh dấu phương pháp thành viên như volatile, lớp hoặc thư viện implementors đang nói một cách hiệu quả "này không được thiết kế để được sử dụng như một đối tượng volatile" - nếu nó đã, sau đó các phương pháp thích hợp hoặc quá tải sẽ cung cấp cho các đối tượng volatile. Tương tự như vậy, điều này áp dụng cho const, trong việc đánh dấu các thành viên như const, họ đang nói "lớp này có thể được sử dụng như là một đối tượng const.

Tại sao volatile cần thiết, những gì các nguồn bên ngoài có thể được sửa đổi shared_ptr" mà không có kiến ​​thức về Nếu có vấn đề về luồng, thì bạn sẽ được phục vụ tốt hơn với một tiện ích thư viện luồng, hoặc nếu yêu cầu đơn giản là tắt tối ưu hóa, các trình biên dịch khác nhau có cơ chế cho việc này (pragmas, vv ..)

+0

Điểm tốt, mặc dù tôi tin rằng sử dụng std :: nguyên tử là hoàn toàn dễ bay hơi với C++ 11 nếu chúng ta thực sự đang nói về luồng. – Atifm

3

Volatile chỉ là một dấu hiệu cho trình biên dịch mà bộ nhớ có thể thay đổi bất ngờ. Tắt một số tối ưu hóa. Dưới sự che chở của nó chỉ là một địa chỉ bộ nhớ.

Con trỏ được chia sẻ chỉ giữ/quản lý tài nguyên. Điều đó nói rằng, kể từ std :: shared_ptr :: get() không được đánh dấu dễ bay hơi, bạn không thể thực sự sử dụng shared_ptr để quản lý một con trỏ dễ bay hơi theo cách có thể truy cập.

Tôi khuyên bạn nên sử dụng con trỏ khỏa thân và sử dụng lối thoát có phạm vi hoặc trình phá hủy để dọn dẹp sau nó.

Nếu bạn đang sử dụng dễ bay hơi vì con trỏ có thể được sửa đổi bởi một chuỗi khác, bạn có thể muốn xem xét sử dụng std :: atomic thay vì dễ bay hơi. Trong luồng công việc luồng, trước std::atomic, các con trỏ được truy cập từ các luồng khác thường được đánh dấu là dễ bay hơi. Đó không phải là thực hành tốt nhất.

+0

thực sự dễ bay hơi không phải là một gợi ý. Một trong những điều mà nó làm là: Mọi truy cập (hoạt động đọc hoặc ghi, gọi hàm thành viên, v.v.) trên đối tượng dễ bay hơi được coi là tác dụng phụ có thể nhìn thấy cho mục đích tối ưu hóa (nghĩa là, trong một chuỗi duy nhất – NathanOliver

+1

Vì chức năng đó không có bộ định mức dễ bay hơi, nên không thể gọi nó với đối tượng dễ bay hơi .... – cpplearner

+0

@nathanOliver đã ghi lại nó như bạn gợi ý. – Atifm

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