2008-10-23 63 views
29

Chỉ cần về mọi đoạn mã ví dụ ở khắp mọi nơi bỏ qua việc xử lý lỗi (vì nó "nhầm lẫn vấn đề" là mã mẫu đang giải quyết). Kiến thức lập trình của tôi chủ yếu đến từ sách và các trang web, và bạn hiếm khi thấy bất kỳ lỗi xử lý nào đang được sử dụng ở đây, hãy để những thứ tốt đẹp.Xử lý lỗi C++ - Nguồn tốt của mã ví dụ?

Một số địa điểm để xem ví dụ điển hình về mã xử lý lỗi C++ ở đâu? Sách cụ thể, các dự án nguồn mở cụ thể (tốt nhất là với các tệp và chức năng để xem), và các trang web hoặc trang web cụ thể sẽ được chấp nhận một cách biết ơn.

Trả lời

41

Herb Sutter và Andrei Alexandrescu của cuốn sách C++ Coding Standards đi kèm với cả một chương về Xử lý lỗi và ngoại lệ bao gồm

  • Khẳng định tự do để ghi lại các giả định nội bộ và bất biến
  • Thiết lập một xử lý chính sách lỗi hợp lý, và theo dõi nó nghiêm ngặt
  • Phân biệt giữa các lỗi và không phải là lỗi
  • Des IGN và ghi lỗi an toàn đang
  • thích sử dụng ngoại lệ đối với báo cáo lỗi
  • Ném bởi giá trị, bắt bằng cách tham khảo
  • Báo cáo, xử lý, và dịch lỗi một cách thích hợp
  • thông số kỹ thuật Tránh ngoại lệ

Mỗi chủ đề cũng bao gồm một ví dụ và tôi thấy nó là một nguồn tài nguyên rất có giá trị.

+1

Rất tốt. Tôi đã thêm nó vào danh sách mua của tôi. (Và tôi cũng sẽ bỏ phiếu cho câu trả lời này, ngay sau khi tôi có thể bỏ phiếu lại. :-)) –

+1

+1, vì đặt tên nguồn và tóm tắt dấu đầu dòng. – paercebal

6

Tôi thích xử lý ngoại lệ được thảo luận trong bài viết này. Nó dẫn đến mã sạch và tránh việc tạo/xóa các đối tượng rõ ràng chỉ để xử lý các ngoại lệ. http://www.informit.com/articles/article.aspx?p=373339

+0

Bài viết hay, cảm ơn. (Tôi không tham gia biểu quyết hôm nay, tôi sẽ bỏ phiếu này trong vài giờ nữa.) –

4

Với C++, bạn nên kết thúc với mã xử lý lỗi ít hiển thị hơn, vì bạn có thể để lại rất nhiều việc nâng hạng nặng cho Ngoại lệ.

Theo tôi, quy tắc cơ bản nhất với ngoại lệ (và một trong những trường hợp thường bị hỏng) chính là điều này. Đừng cố bắt ngoại lệ trừ khi bạn có kế hoạch cụ thể để xử lý chúng.

Với trường hợp ngoại lệ, bạn không phải lo lắng về mã lỗi được trả về từ hàm, vì chức năng được thiết kế tốt sẽ chỉ ném ngoại lệ.

Trong C một lỗi điển hình kịch bản xử lý như sau:

int DoA() 
{ 
if (location == hellInAHandcart) 
    return ERROR; 
else 
    RETURN OK; 
} 

int DoB() 
{ 
    int err = DoA(); 
    if (err != OK) 
    return err; 
    else 
    return DoSomethingElse1(); 
} 

int DoC() 
{ 
    int err = DoB(); 
    if (err != OK) 
    //Handle My error here in whatever way... 
} 

Trong khi trong C++ ...

void DoA() 
{ 
if (location == hellInAHandcart) 
    throw Exception("Gone To Hell in a Handcart"); 
} 

void DoB() 
{ 
    DoA(); 
    DoSomethingElse1(); 
} 

void DoC() 
{ 
    try 
    { 
    DoB(); 
    } 
    catch (Exception &E) 
    { 
    // Handle My error here in whatever way... 
    } 
} 
+0

Điều đó, với phần "trong bất kỳ cách nào" được điền vào, chính xác là loại điều tôi đang tìm kiếm. –

+0

Bạn comparaison là không chính xác với tôi. Trong phiên bản C, bạn kiểm tra kết quả của DoA trước DoSomethingElse1. – olipion

+0

@olipion: Có, bởi vì nó có thể trả về mã lỗi. Với các ngoại lệ, nó không cần trả lại mã lỗi, vì vậy không có gì để kiểm tra. – Roddy

13

"Sử dụng ngoại lệ" vs "Sử dụng mã lỗi" không bao giờ rõ ràng như các ví dụ đề xuất.

Sử dụng mã lỗi cho luồng chương trình. Nếu bạn có lỗi được mong đợi, đừng ném ngoại lệ. Ví dụ.bạn đang đọc tệp, bạn có thể ném một ngoại lệ cho "không tìm thấy tệp", "tệp bị khóa"; nhưng không bao giờ ném một cho "kết thúc tệp".

Nếu bạn làm thế, bạn không bao giờ có thể viết các vòng lặp đơn giản, bạn sẽ luôn gói mã trong các trình xử lý ngoại lệ. Và đừng quên các ngoại lệ rất chậm, điều này đặc biệt quan trọng trong các máy chủ đa luồng lớn. (Không quan trọng lắm trong ứng dụng máy tính để bàn của bạn).

Thứ hai, hãy rất cẩn thận với phân cấp ngoại lệ. Bạn có thể nghĩ rằng có thể có một lớp học Exception, sau đó lấy một số NetException từ đó, sau đó SMTPException cho lớp SMTP của bạn. Nhưng trừ khi bạn giữ dữ liệu chung trong lớp cơ sở, bạn sẽ luôn phải nắm bắt mọi loại ngoại lệ trong phân cấp đó. Ví dụ. nếu bạn đặt lý do cho lỗi SMTP trong lớp học SMTPException của mình, bạn phải nắm bắt nó - nếu bạn chỉ bắt được Exception loại, bạn sẽ không có quyền truy cập vào các thành viên SMTPException. Cách giải quyết tốt cho vấn đề này là có một chuỗi và một thành viên int trong lớp ngoại lệ cơ sở và chỉ sử dụng chúng, ngay cả đối với các kiểu có nguồn gốc. Thật không may std::exception chỉ cung cấp một chuỗi :(

Một số người nói rằng làm điều này có nghĩa bạn có thể cũng chỉ có một loại ngoại lệ duy nhất, đặc biệt là khi bạn sẽ luôn luôn nắm bắt những lớp cơ sở gõ anyway.

Nếu bạn làm sử dụng các trường hợp ngoại lệ, bạn phải có những rắc rối để cư trú chúng với nhiều dữ liệu hơn bạn sẽ với một mã lỗi.Với lỗi, bạn phải xử lý chúng ngay lập tức hoặc họ bị lạc trong mã. đã được ném - như trong ví dụ của Roddy DoC được gọi, và nhận được một ngoại lệ 2 cấp độ từ DoA. Trừ khi bạn chỉ định lỗi được cụ thể cho mã trong DoA, bạn có thể nghĩ rằng nó đã được ném từ DoB chức năng. (ví dụ đơn giản, nhưng tôi đã nhìn thấy mã nơi một ngoại lệ được xử lý nhiều cấp độ xuống ngăn xếp cuộc gọi. Đó là ab st thứ để gỡ lỗi. Điều này đặc biệt áp dụng cho các chương trình OO)

Vì vậy, hy vọng, tôi đã đưa ra bạn đủ để suy nghĩ về. Sự thật đơn giản của vấn đề là phong cách đó có nghĩa là không có gì trong việc xử lý lỗi, tính thiết thực là mọi thứ. Nếu bạn phải đặt báo cáo đăng nhập ở khắp mọi nơi thì có thể xảy ra lỗi, sau đó làm như vậy. Nó quan trọng hơn rất nhiều mà bạn có thể nhìn thấy nơi mã đã đi sai (và những dữ liệu đã được làm việc với) hơn bạn có một hệ thống cấp bậc ngoại lệ thanh lịch hoặc bạn đã rải rác mã của bạn với xử lý ngoại lệ. Nếu bạn không thể dễ dàng theo dõi lỗi, mã xử lý lỗi của bạn là vô dụng.

Trường hợp ngoại lệ tốt, hãy sử dụng chúng. Nhưng hãy nghĩ về những gì bạn đang làm, đừng lạm dụng hoặc lạm dụng chúng. Một ngoại lệ bị lạm dụng tồi tệ hơn là không xử lý lỗi ở tất cả (vì bạn có thể lấy một bãi chứa sự cố và xem ngoại lệ chưa được giải quyết để tìm lỗi trong vài giây. Với một ngoại lệ được ăn và bỏ qua, bạn đang nhồi).

Tôi đã tìm thấy trong những năm qua rằng trợ lý gỡ lỗi lớn nhất đang đăng nhập. Viết nhật ký, viết nhiều nhật ký.

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