您好,登錄后才能下訂單哦!
我們在之前學習了 C++ 中有關異常的知識,現在我們來重新回顧下。那么異常的格式是什么呢?便是 try ... catch ...;try 語句處理正常的代碼邏輯,而 catch 語句則處理異常情況,try 語句中的異常由對應的 catch 語句處理。格式如下
try { double r = divide(1, 0); } catch(...) { cout << "Divided by zero ..." << endl; }
在 C++ 中,通過 throw 語句拋出異常信息。throw 拋出的異常必須被 catch 處理,當前函數如果能處理異常,程序將繼續往下執行;如果當前函數無法處理異常則函數停止執行并返回。未被處理的異常會順著函數調用棧向上傳播,直到被處理為止,否則程序將停止執行。如下
同一個 try 語句可以跟上多個 catch 語句。catch 語句可以定義具體處理的異常類型,不同類型的異常由不同的 catch 語句負責處理;try 語句中可以拋出任何類型的異常,catch(...) 用于處理所有類型的異常,任何異常都只能被捕獲(catch)一次。異常處理的匹配規則如下
異常的類型可以是自定義類類型,對于類類型異常的匹配依舊是至上而下嚴格匹配,賦值兼容性原則在異常匹配中依然適用。一般而言:匹配子類異常的 catch 放在上部,匹配父類異常的 catch 放在下部。現代 C++ 庫中必然包含充要的異常類族,因為異常類是數據結構類所依賴的“基礎設施”!舉個例子,如果我們在申請內存失敗時便要但會一個內存不足的異常。異常類如下圖所示
下來我們來看看異常類功能定義,如下
下來我們來創建一個異常類族,代碼如下
Exception.h 源文件
#ifndef EXCEPTION_H#define EXCEPTION_H #include "Object.h" namespace DTLib { class Exception : public Object { private: char* m_message; char* m_location; void init(const char* message, const char* file, int line); public: Exception(const char* message); Exception(const char* file, int line); Exception(const char* message, const char* file, int line); Exception(const Exception& e); Exception& operator= (const Exception& e); virtual const char* message() const; virtual const char* location() const; virtual ~Exception(); }; #endif // EXCEPTION_H
Exception.cpp 源碼如下
#include "Exception.h"#include <cstring> #include <cstdlib> using namespace std; namespace DTLib { void Exception::init(const char* message, const char* file, int line) { m_message = strdup(message); if( file != NULL ) { char s1[16] = {0}; itoa(line, s1, 10); m_location = static_cast<char*>(malloc(strlen(file) + strlen(s1) + 2)); m_location = strcpy(m_location, file); m_location = strcat(m_location, ":"); m_location = strcat(m_location, s1); } else { m_location = NULL; } } Exception::Exception(const char* message) { init(message, NULL, 0); } Exception::Exception(const char* file, int line) { init(NULL, file, line); } Exception::Exception(const char* message, const char* file, int line) { init(message, file, line); } Exception::Exception(const Exception& e) { m_message = strdup(e.m_message); m_location = strdup(e.m_location); } Exception& Exception::operator= (const Exception& e) { if( this != &e ) { free(m_message); free(m_location); m_message = strdup(e.m_message); m_location = strdup(e.m_location); } return *this; } const char* Exception::message() const { return m_message; } const char* Exception::location() const { return m_location; } Exception::~Exception() { free(m_message); free(m_location); } }
main.cpp 源文件如下
#include <iostream>#include "Exception.h" using namespace std; using namespace DTLib; int main() { try { throw Exception("test", __FILE__, __LINE__); } catch(const Exception& e) { cout << "catch(const Exception& e)" << endl; cout << e.message() << endl; cout << e.location() << endl; } return 0; }
下來我們來看看編譯結果
我們看到拋出了一個異常,它的文件名是 test,行號是 11 行。我們可以在 Exception.h 頭文件添加一個宏,用來顯示文件名及行號,定義如下
#define THROW_EXCEPTION(e, m) (throw e(m, __FILE__, __LINE__))
然后將 mian.cpp 中的 throw 語句中的拋異常改為下面這樣
THROW_EXCEPTION(Exception, "test");
編譯結果如下
我們看到效果是一樣的。那么在可復用代碼庫設計時,盡量使用賣你想對象技術進行架構,盡量使用異常處理機制分類正常邏輯和異常邏輯。通過今天對異常類的學習,總結如下:1、C++ 中國直接支持異常處理的概念,try ... catch ... 是 C++ 中異常處理的專用語句;2、try 語句處理的是正常代碼邏輯,catch 語句處理的是異常情況;3、同一個 try 語句可以跟上多個 catch 語句,異常處理必須嚴格匹配,不進行任何的類型轉換;4、現代 C++ 庫必然包含充要的異常類族,所有庫中的數據結構都依賴于異常機制;5、異常機制能夠分離庫中代碼的正常邏輯個異常邏輯。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。