2012-03-15 43 views
5
void f(boost::shared_ptr<int> ptr) 
{ 
    if (ptr) // should we check? 
     // do something 
} 

void f2(int *p) 
{ 
    if (p) // good practice to check before using it 
     // do something 
} 

Câu hỏi: Chúng tôi có nên xác thực shared_ptr trước khi chúng tôi sử dụng không?Tôi có nên kiểm tra tăng :: shared_ptr hoặc std :: shared_ptr trước khi tôi sử dụng không?

+0

Chỉ cần sử dụng hàm ** use_count ** để kiểm tra số lượng tham chiếu và không có thông tin cần kiểm tra. – softghost

Trả lời

0

Có. shared_ptr chỉ cung cấp cho bạn lợi ích của nó khi biết khi nào phát hành bộ nhớ được cấp phát bằng cách đếm các tham chiếu đến nó. Bạn vẫn nên xác minh xem nó có hợp lệ không trước khi sử dụng nó, giả sử bạn không có cách nào khác để biết trước rằng nó chắc chắn sẽ không rỗng, nhưng đó là vấn đề của việc bạn đang sử dụng shared_ptr hay không.

+2

Trong khi đây là lời khuyên chung tốt, cần lưu ý rằng, giống như các con trỏ khác, nếu con trỏ không thể rỗng vì một số biến thể của chương trình/lớp, thì nó không cần được kiểm tra. Ví dụ, nếu một thành viên riêng được chia sẻ con trỏ được thiết lập và kiểm tra trong constructor và sau đó là không bao giờ tái giao, không cần phải kiểm tra nó trong mỗi cuộc gọi chức năng thành viên. –

+0

André là đúng. – Almo

+0

@ André: Hoặc nó phải được kiểm tra trong một 'khẳng định'. – ildjarn

5

No. Nếu nó nằm trong hợp đồng của hàm phải hợp lệ, thì cách nhanh nhất để thu hút sự chú ý đến thực tế là người gọi có lỗi là lỗi. Thất bại càng sớm càng tốt.

+0

Vấn đề với điều này là về mặt kỹ thuật nó sẽ chỉ gây ra UB; không có sự bảo đảm nào của một lỗi _observable_, vô số sự cố. – ildjarn

+2

@ildjarn: "Thất bại sớm nhất có thể" - 'khẳng định'. :) – Xeo

+0

+1 vì đó là chính xác những gì tôi làm. Những điều thông minh tiêu biểu mà bạn sẽ không nghe thấy trong các khóa học lập trình vũ trụ do các giáo sư không phải là lập trình viên không có năng lực điều hành. – ceztko

3

Phụ thuộc vào việc nó thực sự là một khả năng trong quá trình thực thi chương trình bình thường mà shared_ptr là không. Nếu không, hãy đẩy trách nhiệm như một điều kiện tiên quyết về người dùng của f và có thể assert(ptr);. Lưu ý rằng nó không chỉ áp dụng cho shared_ptr, nhưng bất kỳ con trỏ nào sử dụng thực sự. Mặc dù bạn có thể chỉ nên sử dụng tài liệu tham khảo ở đây.

+0

Tôi đặc biệt không liệt kê câu hỏi bằng cách cung cấp một hàm có tham số tham chiếu b/c, chúng tôi giả định rằng tham chiếu không được trỏ đến một con trỏ trống và chúng tôi luôn không cần kiểm tra tham chiếu. Tuy nhiên, bạn vẫn có thể làm cho nó không hợp lệ bằng cách nào đó. – q0987

2

Phụ thuộc vào kịch bản của bạn:

Nếu f() là một hàm public function/API mà bạn không kiểm soát được những gì ai đó có thể vượt qua bạn sau đó có bạn nên kiểm tra.

Nếu hàm là một hàm thành viên riêng tư hoặc được ghi lại là yêu cầu một con trỏ hợp lệ thì tôi sẽ sử dụng assert. Nó có một số lượng lớn không có phí trong bản phát hành bản phát hành và nhanh chóng hiển thị vấn đề trong quá trình gỡ lỗi.

void f(shared_ptr<T> ptr) 
{ 
    assert(ptr && "ptr is null!"); 

    ..... 
} 
+1

Không thích khẳng định để xác thực giá trị thời gian chạy khi bạn nhận được hành vi khác nhau trong gỡ lỗi và phát hành. Assert nên được dành riêng cho các ứng dụng bất biến không cho kiểm tra thời gian chạy. –

0

Hãy nói: nếu void foo(shared_ptr<int> ptr) của bạn là một thư viện mục đích chung và bạn muốn thông báo cho người sử dụng trong thời gian chạy rằng giá trị nullptr không được hỗ trợ (ném một ngoại lệ) hoặc nó được xử lý bằng một codepath khác nhau có, nó là đúng để kiểm tra. Nếu bạn không cần lưu trữ shared_ptr ở đâu đó với số foo() và bạn chỉ cần đảm bảo chức năng sẽ không hỗ trợ con trỏ null, chỉ cần chuyển một tham chiếu, ví dụ void foo(int &integer). Đối với các trình biên dịch mà tôi biết, các tham chiếu là phần lớn các con trỏ không có giá trị null (tùy thuộc vào các lựa chọn tối ưu hóa).

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