2010-06-30 30 views
20

Tiêu đề khá nhiều tổng kết câu hỏi của tôi. Tại sao không thể thực hiện các bước sau để kiểm tra con trỏ rỗng?Tại sao không auto_ptr <T> có toán tử!() Được xác định?

auto_ptr<char> p(some_expression); 
// ... 
if (!p) // error 

này phải được thực hiện thay vì:

if (!p.get()) // OK 

Tại sao không auto_ptr<T> chỉ đơn giản là đã operator!() được xác định?

+0

Câu hỏi http://stackoverflow.com/q/2953530/427532 có phần liên quan. –

Trả lời

19

Dường như đã có lỗi trong thiết kế của nó. Điều này sẽ được sửa trong C++ 0x. unique_ptr (thay thế cho auto_ptr) chứa explicit operator bool() const;

Trích từ mới C++ Standard:

Lớp mẫu auto_ptr bị phản đối. [Lưu ý: Mẫu lớp unique_ptr (20.9.10) cung cấp giải pháp tốt hơn . -end note]


Một số làm rõ:
Q: Có gì sai với a.get() == 0?
A: Không có gì sai với a.get()==0, nhưng con trỏ thông minh cho phép bạn làm việc với chúng vì chúng là con trỏ thực. Bổ sung operator bool() mang lại cho bạn một sự lựa chọn như vậy. Tôi nghĩ rằng, lý do thực sự để làm cho auto_ptr không được chấp nhận là điều đó đã không có thiết kế trực quan. Nhưng operator bool cho unique_ptr trong Tiêu chuẩn mới có nghĩa là không có lý do nào để không có nó.

+0

Câu hỏi "ngu ngốc": 'rõ ràng' ở đây có nghĩa là gì? Tôi đã từng thấy nó với các nhà xây dựng. –

+3

Nó có nghĩa là điều tương tự với các nhà xây dựng - rằng nhà xây dựng hoặc nhà điều hành chuyển đổi không tham gia vào điệu nhảy chuyển đổi tiềm ẩn xảy ra khi bạn cố chuyển một đối tượng đến hàm mong đợi một arg của một kiểu khác nhau –

+0

Chắc chắn, 'auto_ptr 'đã không được chấp nhận nhưng tại sao nó là một lỗi thiết kế không có' toán tử!() '? Có gì sai với 'a.get() == 0'? –

8

Nói một cách đơn giản, cần có operator !() được xác định. auto_ptr không phải là một container được thiết kế rất tốt. Các con trỏ thông minh trong tăng có toán tử chuyển đổi operator bool() được xác định có thể bị từ chối với operator !(). Điều đó sẽ cho phép if(!p) biên dịch và hoạt động như mong đợi.

+9

"' auto_ptr' không phải là một container được thiết kế rất tốt "tổng hợp nó lên khá độc đáo. – Cogwheel

+3

'auto_ptr' không phải là vùng chứa. Ngoài ra tại sao nó phải có 'toán tử!()' Được định nghĩa? Nếu bạn định tuyên bố điều này, thì tôi nghĩ bạn cần phải biện minh cho tuyên bố này. Tôi không thể thấy bất kỳ lý do cố hữu nào để xác định nó; nó không phải là mặc dù 'if (a.get() == 0)' là không rõ ràng hoặc khó sử dụng. –

+3

Nếu một cái gì đó được thiết kế để hoạt động như một con trỏ thông minh hơn, thì giao diện của nó sẽ giống như một con trỏ. – Cogwheel

0

Tôi nghi ngờ bởi vì nó được dự kiến ​​rằng đi qua khoảng auto_ptr s đến null sẽ là một trường hợp hiếm hoi, để tránh thêm giao diện bổ sung, và để làm cho nó rõ ràng khi thực sự kiểm tra cho null.

+0

Cho rằng auto_ptr :: operator = chuyển quyền sở hữu và đặt auto_ptr nguồn thành null, auto_ptr thành null có thể khá phổ biến. –

4

Có vấn đề với chuyển đổi boolean. Nó cho phép các cú pháp gần như luôn luôn là một nỗi đau.

Có, thật may mắn là một giải pháp: thành ngữ Safe Bool.

Sự cố với chuyển đổi thành bool là chuyển đổi tiềm ẩn nguy hiểm.

std::auto_ptr<T> p = ..., q = ....; 

if (p < q) // uh ? 

Do đó, operator bool() const là một sự ghê tởm. Hoặc bạn cung cấp một phương pháp rõ ràng ... hoặc bạn sử dụng thành ngữ bool an toàn.

Ý tưởng về thành ngữ là cung cấp cho bạn một thể hiện của một loại với một tập hợp con khá nhỏ về các thao tác và hầu như không có trường hợp chuyển đổi ẩn sẽ khiến bạn gặp rắc rối. Điều này được thực hiện bằng cách sử dụng một con trỏ đến hàm thành viên.

Thao tác như if (p)if (!p) sau đó có ý nghĩa, nhưng if (p < q) sẽ không biên dịch được.

Đọc kỹ liên kết để biết giải pháp hoàn chỉnh và bạn sẽ nhận ra lý do tại sao không nên có operator bool() const.

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