2017-01-19 16 views
10

tôi đang học C++ và tôi đang trải qua khi tôi cố gắng và tạo ra ngoại lệ của riêng tôi và ném chúng trên Linux.Tạo ngoại lệ tùy chỉnh trong C++

tôi đã tạo ra một dự án thử nghiệm nhỏ để kiểm tra việc thực hiện của tôi và dưới đây là ngoại lệ tập tin header lớp học của tôi.

class TestClass : public std::runtime_error 
{ 
public: 
    TestClass(char const* const message) throw(); 
    virtual char const* what() const throw(); 
}; 

Nguồn tập tin cho các lớp ngoại lệ là

using namespace std; 

TestClass::TestClass(char const* const message) throw() 
    : std::runtime_error(message) 
{ 

} 

char const * TestClass::what() const throw() 
{ 
    return exception::what(); 
} 

Trong ứng dụng chính của tôi, tôi gọi một chức năng mà ném ngoại lệ của tôi và bắt nó trong một try/catch như sau:

void runAFunctionAndthrow(); 

/* 
* 
*/ 
int main(int argc, char** argv) { 
    try 
    { 
     cout << "About to call function" << endl; 
     runAFunctionAndthrow(); 
    } 
    catch (TestClass ex) 
    { 
     cout << "Exception Caught: " << ex.what() << endl; 
    } 

    return 0; 
} 

void runAFunctionAndthrow() 
{ 
    cout << "going to run now. oh dear I need to throw an exception" << endl; 

    stringstream logstream; 
    logstream << "This is my exception error. :("; 
    throw TestClass(logstream.str().c_str()); 
} 

Khi tôi chạy tôi đang mong đợi để có được kết quả như sau:

About to call function

Going to run now. oh dear I need to throw an exception

Exception Caught: This is my exception error. :(

Thay vì những gì tôi nhận được là

About to call function

going to run now. oh dear I need to throw an exception

Exception Caught: std::exception

Chú ý dòng cuối cùng nó nói std :: ngoại lệ thay vì thông điệp ngoại lệ thực tế của tôi "Đây là lỗi ngoại lệ của tôi".

Tại sao điều này, nó hoạt động OK trên Windows nhưng trên Linux nó thực hiện điều này.

Từ những gì tôi đã nhìn thấy trên bài viết khác nhau những gì tôi đã làm là đúng vì vậy những gì tôi thiếu.

+0

Trong 'what()' bạn có thể có nghĩa là 'return runtime_error :: what();' - sẽ bỏ qua việc thực thi lại hoàn toàn (hành vi lớp cơ sở ở đây đã tốt cho bạn). –

Trả lời

17

bạn what() lợi nhuận:

return exception::what(); 

Giá trị trả về từ std::exception::what()specified as follows:

Pointer to a null-terminated string with explanatory information.

Vậy là xong. Không có gì hơn, không có gì khác. Văn bản bạn đang hiển thị chắc chắn đủ điều kiện là "thông tin giải thích". Và đây là yêu cầu duy nhất cho giá trị trả về của what() (ngoại trừ một giá trị khác không phải là germane ở đây).

Nói cách khác, C++ không đảm bảo các nội dung chính xác về những gì bạn nhận được với what(). what() bạn thấy là what() bạn nhận được, như nói đi.

Nếu bạn muốn ngoại lệ của mình tự mô tả, theo một cách nào đó, bạn có thể thực hiện điều đó, như một phần của what().

+1

Cho rằng 'TestClass' thừa hưởng' std :: runtime_error' nó chỉ có thể tránh reimplementing 'what()' - 'std :: runtime_error :: what()' đã trả về thông điệp được truyền cho hàm tạo của nó. –

+0

@MatteoItalia Tôi vừa mới nhận thấy điều đó và đã thử trước khi nhận xét của bạn từ lời giải thích của bạn và nó làm những gì tôi mong đợi bây giờ. Cảm ơn sự giúp đỡ của bạn – Boardy

0

Bạn cần một cách để xác định một thông báo lỗi tùy chỉnh để std :: ngoại lệ mà afaik không được phép. Xem this để có giải pháp khả thi.

8

Bạn cần thực hiện riêng của bạn về những gì() phương pháp hoặc sử dụng std::runtime_error::what() như được viết trong ý kiến ​​

Say:

class TestClass : public std::runtime_error 
{ 
    std::string what_message; 
public: 
    const char* what() override 
    { 
     return what_message.c_str(); 
    } 
}; 

Ngoài ra, tốt hơn sử dụng noexcept thay vì throw() và chỉ sau khi bạn đọc về họ - link.

Và trong try-catch của bạn:

catch (const TestClass& myException) 

Thay vì catch(TestClass myException) - nếu bạn làm một bản sao tiềm ẩn mà có khả năng có thể dẫn đến một ném ngoại lệ. Nó cũng phá vỡ đa hình: nếu bạn muốn catchpure virtual interface ví dụ triển khai, bạn sẽ cần sử dụng tham chiếu.

+0

Ah tốt để biết cảm ơn, cảm ơn cho các thông tin thêm. – Boardy

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