Tôi đã thử nhiều cách khác nhau; công trình này cho tôi:
Bắt đầu bằng cách subclassing runtime_error:
/*----------------------------------------------------------------------*/
/* subclass runtime_error for safe exceptions in try/throw/catch */
#include <stdexcept>
/* a little preprocessor magic here -- makes a subclass of runtime_error*/
#define NEWERROR(NE) class NE : public runtime_error { \
public: NE (string const& error) : runtime_error(error) {} }
NEWERROR(FileError );
NEWERROR(NetworkError );
NEWERROR(StringError );
NEWERROR(CofeeError );
/*----------------------------------------------------------------------*/
Sau đó, bạn có thể tạo ra một số trường hợp ngoại lệ của bạn.
/*----------------------------------------------------------------------*/
/* some example pre-defined exceptions */
FileError ReadOnly ("ReadOnly" );
FileError FileNotFound ("FileNotFound" );
NetworkError TimeOutExceeded ("TimeOutExceeded" );
NetworkError HostNotFound ("HostNotFound" );
CoffeeError OutOfCoffee ("OutOfCoffee" );
/*----------------------------------------------------------------------*/
Rõ ràng thông báo cho trình biên dịch rằng chức năng của bạn có thể ném một ngoại lệ hoặc chương trình có thể sẽ chấm dứt tại điểm ném, và dữ liệu có thể bị mất hoặc bị hỏng nếu nguồn lực đang được sử dụng vào thời điểm đó.
"Đảm bảo bạn có thể và bắt bất cứ thứ gì bạn có thể ném."
(tôi sử dụng generic runtime_error vì ném và bắt nó bao gồm tất cả các trường hợp ngoại lệ của tôi cộng với những người của hệ thống là tốt.)
/*----------------------------------------------------------------------*/
/* example function that may throw an exception */
#include <fstream>
ifstream& getFileStream (string fname) throw (runtime_error)
{
if (fname == "")
throw StringError("<getFileStream> fname:empty string");
// processing stops here if thrown
try
{
ifstream Inputfstream;
ifstream& ifsref = Inputfstream;
// ifstream has its own <legacy> exception
// mechanisms and procedures
ifsref.exceptions (ifstream::failbit | ifstream::badbit);
ifsref.open (fname , ifstream::in); // could fail ==> ifstream::failure exception
}
catch (ifstream::failure e)
{
throw FileError(fname + string(e.what()));
}
return ifsref;
}
/*----------------------------------------------------------------------*/
sau đó trong thử của bạn/catch
/*----------------------------------------------------------------------*/
catch (FileNotFound fnf) //catch a specific error
{
if (DEBUG) cerr << "[File Not Found Error: " << fnf.what() << "]" << endl;
... (handle it) ...
}
catch (FileError fe) //catch a specific type
{
if (DEBUG) cerr << "[File Error: " << fe.what() << "]" << endl;
... (handle it) ...
}
catch (runtime_error re) // catch a generic type
{
if (DEBUG) cerr << "[Runtime error: " << re.what() << "]" << endl;
// determine type by string comparison
if (re.what() == string("ResourceNotavailable")) ...
if (re.what() == string("NetWorkError") ) ...
...
}
catch (...) // catch everything else
{ ... exit, rethrow, or ignore ... }
/*----------------------------------------------------------------------*/
Lớp thời gian chạy lỗi có hỗ trợ tốt trong thư viện chuẩn C++, và trình biên dịch biết về nội bộ và cách tối ưu hóa bộ nhớ và công văn, để bạn có thể sử dụng chúng trên các cơ sở mã khác nhau một cách an toàn và tự tin. Mã này là xách tay và tương thích với nhiều trình biên dịch và kiến trúc khác nhau. Có thể thích hợp hơn và nhanh hơn khi bắt từng lỗi riêng biệt trong một điều khoản bắt, từ cụ thể hơn đến chung hơn, nếu bạn cảm thấy một chuỗi các kết quả chuỗi là một sự lãng phí khủng khiếp của cpu và bộ nhớ.).
<stdexcept>
cung cấp cho bạn một số loại ngoại lệ trong 2 nhóm:
cú pháp sử dụng hơi khác nhau đối với một số người trong số họ.
Wisdom thông thường trong C++ nói rằng trường hợp ngoại lệ của bạn nên được tương đối "phẳng", có nghĩa là hệ thống phân cấp lớn các loại cụ thể của trường hợp ngoại lệ nên tránh làm trong ủng hộ của những người thân chung nhưng thông tin ngắn cho công việc lập trình nói chung. Các nhiệm vụ cụ thể của miền như logic hệ thống mạng, toán học cao hơn, v.v. có thể được hưởng lợi từ tính đặc hiệu, nhưng điều đó có thể đạt được bằng cách tạo các chuỗi lỗi thông minh với các ngoại lệ thời gian chạy/logic chung.
Cuối cùng, điểm của tôi là: Bạn có thể đạt được tất cả điều này bằng cách ném và chỉ bắt runtime_error.
Bạn không cần phải tạo ra toàn bộ các túi ngoại lệ đặc biệt cao (giống như java) cho mỗi lớp, mỗi xử lý một lỗi cụ thể.
u có thể giải thích tại sao bạn cần nó? có lẽ chúng ta có thể tìm kiếm các lựa chọn thay thế? –
Tôi rõ ràng không bao giờ làm điều này mã hóa một cái gì đó từ đầu, nhưng theo những hoàn cảnh cụ thể tôi dưới nó sẽ hữu ích. Mã kế thừa. –