中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

亞馬遜雨林破壞現(xiàn)狀/文章優(yōu)化關(guān)鍵詞排名

亞馬遜雨林破壞現(xiàn)狀,文章優(yōu)化關(guān)鍵詞排名,佛山網(wǎng)站代運(yùn)營,淮安哪里有做網(wǎng)站的文章目錄 一、C語言傳統(tǒng)的處理錯(cuò)誤的方式二、 C異常概念三、異常的使用1.異常的拋出和捕獲2.異常的重新拋出3.異常安全4.異常規(guī)范 四、自定義異常體系五、C標(biāo)準(zhǔn)庫的異常體系(了解)六、異常的優(yōu)缺點(diǎn) 一、C語言傳統(tǒng)的處理錯(cuò)誤的方式 傳統(tǒng)的錯(cuò)誤處理機(jī)制&am…

文章目錄

  • 一、C語言傳統(tǒng)的處理錯(cuò)誤的方式
  • 二、 C++異常概念
  • 三、異常的使用
    • 1.異常的拋出和捕獲
    • 2.異常的重新拋出
    • 3.異常安全
    • 4.異常規(guī)范
  • 四、自定義異常體系
  • 五、C++標(biāo)準(zhǔn)庫的異常體系(了解)
  • 六、異常的優(yōu)缺點(diǎn)


一、C語言傳統(tǒng)的處理錯(cuò)誤的方式

  • 傳統(tǒng)的錯(cuò)誤處理機(jī)制:
  1. 終止程序,如assert,缺陷:用戶難以接受。如發(fā)生內(nèi)存錯(cuò)誤,除0錯(cuò)誤時(shí)就會終止程序。
  2. 返回錯(cuò)誤碼,缺陷:需要程序員自己去查找對應(yīng)的錯(cuò)誤。如系統(tǒng)的很多庫的接口函數(shù)都是通過把錯(cuò)誤碼放到errno中,表示錯(cuò)誤實(shí)際中C語言基本都是使用返回錯(cuò)誤碼的方式處理錯(cuò)誤,部分情況下使用終止程序處理非常嚴(yán)重的錯(cuò)誤。

二、 C++異常概念

異常是一種處理錯(cuò)誤的方式,當(dāng)一個(gè)函數(shù)發(fā)現(xiàn)自己無法處理的錯(cuò)誤時(shí)就可以拋出異常,讓函數(shù)的直接或間接的調(diào)用者處理這個(gè)錯(cuò)誤。

  • throw: 當(dāng)問題出現(xiàn)時(shí),程序會拋出一個(gè)異常。這是通過使用 throw 關(guān)鍵字來完成的。
  • catch: 在您想要處理問題的地方,通過異常處理程序捕獲異常.catch 關(guān)鍵字用于捕獲異常,可以有多個(gè)catch進(jìn)行捕獲。
  • try: try 塊中的代碼標(biāo)識將被激活的特定異常,它后面通常跟著一個(gè)或多個(gè) catch 塊。

如果有一個(gè)塊拋出一個(gè)異常,捕獲異常的方法會使用 trycatch 關(guān)鍵字。try 塊中放置可能拋出異常的代碼,try 塊中的代碼被稱為保護(hù)代碼。使用 try/catch 語句的語法如下所示:

try
{// 保護(hù)的標(biāo)識代碼
}
catch (ExceptionName e1)
{// catch 塊
}
catch (ExceptionName e2)
{// catch 塊
}
catch (ExceptionName eN)
{// catch 塊
}

三、異常的使用

1.異常的拋出和捕獲

  • 異常的拋出和匹配原則
  1. 異常是通過拋出對象而引發(fā)的,該對象的類型決定了應(yīng)該激活哪個(gè)catch的處理代碼。

  2. 選中的處理代碼是調(diào)用鏈中與該對象類型匹配且離拋出異常位置最近的那一個(gè)。

  3. 拋出異常對象后,會生成一個(gè)異常對象的拷貝,因?yàn)閽伋龅漠惓ο罂赡苁且粋€(gè)臨時(shí)對象,所以會生成一個(gè)拷貝對象,這個(gè)拷貝的臨時(shí)對象會在被catch以后銷毀。(這里的處理類似于函數(shù)的傳值返回)。

  4. catch(…)可以捕獲任意類型的異常,問題是不知道異常錯(cuò)誤是什么。

  5. 實(shí)際中拋出和捕獲的匹配原則有個(gè)例外,并不都是類型完全匹配,可以拋出的派生類對象,使用基類捕獲,這個(gè)在實(shí)際中非常實(shí)用,我們后面會詳細(xì)講解這個(gè)。

  • 在函數(shù)調(diào)用鏈中異常棧展開匹配原則
  1. 首先檢查throw本身是否在try塊內(nèi)部,如果是再查找匹配的catch語句。如果有匹配的,則調(diào)到catch的地方進(jìn)行處理。
  2. 沒有匹配的catch則退出當(dāng)前函數(shù)棧,繼續(xù)在調(diào)用函數(shù)的棧中進(jìn)行查找匹配的catch。
  3. 如果到達(dá)main函數(shù)的棧,依舊沒有匹配的,則終止程序。上述這個(gè)沿著調(diào)用鏈查找匹配的catch子句的過程稱為棧展開。所以實(shí)際中我們最后都要加一個(gè)catch(...)捕獲任意類型的異常,否則當(dāng)有異常沒捕獲,程序就會直接終止。
  4. 找到匹配的catch子句并處理以后,會繼續(xù)沿著catch子句后面繼續(xù)執(zhí)行。

外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳

double Division(int a, int b)
{// 當(dāng)b == 0時(shí)拋出異常if (b == 0)throw "Division by zero condition!";	//異常后會跳轉(zhuǎn)到catch函數(shù)elsereturn ((double)a / (double)b);
}void Func()
{int len, time;cin >> len >> time;cout << Division(len, time) << endl;
}int main()
{try {Func();}catch (const char* errmsg){		//很多常見數(shù)據(jù)都是不可修改的,因此很多情況下都要用constcout << errmsg << endl;}catch (...) {cout << "unkown exception" << endl;}return 0;
}

2.異常的重新拋出

有可能單個(gè)的catch不能完全處理一個(gè)異常,在進(jìn)行一些校正處理以后,希望再交給更外層的調(diào)用鏈函數(shù)來處理,catch則可以通過重新拋出將異常傳遞給更上層的函數(shù)進(jìn)行處理。

double Division(int a, int b)
{// 當(dāng)b == 0時(shí)拋出異常if (b == 0){throw "Division by zero condition!";}return (double)a / (double)b;
}void Func()
{// 這里可以看到如果發(fā)生除0錯(cuò)誤拋出異常,另外下面的array沒有得到釋放。// 所以這里捕獲異常后并不處理異常,異常還是交給外面處理,這里捕獲了再// 重新拋出去。int* array = new int[10];try {int len, time;cin >> len >> time;cout << Division(len, time) << endl;}catch (...){cout << "delete []" << array << endl;delete[] array;throw;}// ...cout << "delete []" << array << endl;delete[] array;
}int main()
{try{Func();}catch (const char* errmsg){cout << errmsg << endl;}return 0;
}

3.異常安全

  • 構(gòu)造函數(shù)完成對象的構(gòu)造和初始化,最好不要在構(gòu)造函數(shù)中拋出異常,否則可能導(dǎo)致對象不完整或沒有完全初始化。
  • 析構(gòu)函數(shù)主要完成資源的清理,最好不要在析構(gòu)函數(shù)內(nèi)拋出異常,否則可能導(dǎo)致資源泄漏(內(nèi)存泄漏、句柄未關(guān)閉等)。
  • C++中異常經(jīng)常會導(dǎo)致資源泄漏的問題,比如在new和delete中拋出了異常,導(dǎo)致內(nèi)存泄漏,在lock和unlock之間拋出了異常導(dǎo)致死鎖,C++經(jīng)常使用RAII來解決以上問題,關(guān)于RAII我們智能指針這節(jié)進(jìn)行講解。

4.異常規(guī)范

  1. 異常規(guī)格說明的目的是為了讓函數(shù)使用者知道該函數(shù)可能拋出的異常有哪些。 可以在函數(shù)的后面接throw(類型),列出這個(gè)函數(shù)可能拋擲的所有異常類型。

  2. 函數(shù)的后面接throw(),表示函數(shù)不拋異常。

  3. 若無異常接口聲明,則此函數(shù)可以拋擲任何類型的異常。

// 這里表示這個(gè)函數(shù)會拋出A/B/C/D中的某種類型的異常
void fun() throw(A,B,C,D);// 這里表示這個(gè)函數(shù)只會拋出bad_alloc的異常
void* operator new (std::size_t size) throw (std::bad_alloc);// 這里表示這個(gè)函數(shù)不會拋出異常
void* operator delete (std::size_t size, void* ptr) throw();// C++11 中新增的noexcept,表示不會拋異常
thread() noexcept;
thread(thread&& x) noexcept;

四、自定義異常體系

實(shí)際使用中很多公司都會自定義自己的異常體系進(jìn)行規(guī)范的異常管理,因?yàn)橐粋€(gè)項(xiàng)目中如果大家隨意拋異常,那么外層的調(diào)用者基本就沒辦法玩了,所以實(shí)際中都會定義一套繼承的規(guī)范體系。這樣大家拋出的都是繼承的派生類對象,捕獲一個(gè)基類就可以了。

外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳

// 服務(wù)器開發(fā)中通常使用的異常繼承體系
class Exception
{
public:Exception(const string& errmsg, int id):_errmsg(errmsg), _id(id){}virtual string what() const{return _errmsg;}
protected:string _errmsg;		//錯(cuò)誤信息int _id;
};class SqlException : public Exception
{
public:SqlException(const string& errmsg, int id, const string& sql):Exception(errmsg, id), _sql(sql){}virtual string what() const{string str = "SqlException:";str += _errmsg;str += "->";str += _sql;return str;}
private:const string _sql;
};class CacheException : public Exception
{
public:CacheException(const string& errmsg, int id):Exception(errmsg, id){}virtual string what() const{string str = "CacheException:";str += _errmsg;return str;}
};class HttpServerException : public Exception
{
public:HttpServerException(const string& errmsg, int id, const string& type):Exception(errmsg, id), _type(type){}virtual string what() const{string str = "HttpServerException:";str += _type;str += ":";str += _errmsg;return str;}
private:const string _type;
};void SQLMgr()
{srand(time(0));if (rand() % 7 == 0){throw SqlException("權(quán)限不足", 100, "select * from name = '張三'");}//throw "xxxxxx";
}void CacheMgr()
{srand(time(0));if (rand() % 5 == 0){throw CacheException("權(quán)限不足", 100);}else if (rand() % 6 == 0){throw CacheException("數(shù)據(jù)不存在", 101);}SQLMgr();
}void HttpServer()
{// ...srand(time(0));if (rand() % 3 == 0){throw HttpServerException("請求資源不存在", 100, "get");}else if (rand() % 4 == 0){throw HttpServerException("權(quán)限不足", 101, "post");}CacheMgr();
}int main()
{while (1){this_thread::sleep_for(chrono::seconds(1));try {HttpServer();}catch (const Exception& e) // 這里捕獲父類對象就可以{// 多態(tài)cout << e.what() << endl;	//調(diào)用重寫的虛函數(shù)}catch (...){cout << "Unkown Exception" << endl;}}return 0;
}

五、C++標(biāo)準(zhǔn)庫的異常體系(了解)

C++ 提供了一系列標(biāo)準(zhǔn)的異常,定義在 std標(biāo)準(zhǔn)庫 中,我們可以在程序中使用這些標(biāo)準(zhǔn)的異常。它們是以父子類層次結(jié)構(gòu)組織起來的,如下所示:

外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳

外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳

說明:實(shí)際中我們可以可以去繼承exception類實(shí)現(xiàn)自己的異常類。但是實(shí)際中很多公司像上面一樣自己定義一套異常繼承體系。因?yàn)镃++標(biāo)準(zhǔn)庫設(shè)計(jì)的不夠好用。

int main()
{try {vector<int> v(10, 5);// 這里如果系統(tǒng)內(nèi)存不夠也會拋異常v.reserve(1000000000);// 這里越界會拋異常v.at(10) = 100;}catch (const exception& e) // 這里捕獲父類對象就可以{cout << e.what() << endl;}catch (...){cout << "Unkown Exception" << endl;}return 0;
}

六、異常的優(yōu)缺點(diǎn)

  • C++異常的優(yōu)點(diǎn):
  1. 異常對象定義好了,相比錯(cuò)誤碼的方式可以清晰準(zhǔn)確的展示出錯(cuò)誤的各種信息,甚至可以包含堆棧調(diào)用的信息,這樣可以幫助更好的定位程序的bug。

  2. 返回錯(cuò)誤碼的傳統(tǒng)方式有個(gè)很大的問題就是,在函數(shù)調(diào)用鏈中,深層的函數(shù)返回了錯(cuò)誤,那么我們得層層返回錯(cuò)誤,最外層才能拿到錯(cuò)誤,具體看下面的詳細(xì)解釋。

    • // 1.下面這段偽代碼我們可以看到ConnnectSql中出錯(cuò)了,先返回給ServerStart,
      ServerStart再返回給main函數(shù),main函數(shù)再針對問題處理具體的錯(cuò)誤。
      // 2.如果是異常體系,不管是ConnnectSql還是ServerStart及調(diào)用函數(shù)出錯(cuò),都不用檢查,因
      為拋出的異常異常會直接跳到main函數(shù)中catch捕獲的地方,main函數(shù)直接處理錯(cuò)誤。
      int ConnnectSql()
      {// 用戶名密碼錯(cuò)誤if (...)return 1;// 權(quán)限不足if (...)return 2;
      }int ServerStart() {if (int ret = ConnnectSql() < 0)return ret;int fd = socket()if(fd < 0return errno;
      }int main()
      {if (ServerStart() < 0)...return 0;
      }
      
  3. 很多的第三方庫都包含異常,比如boost、gtest、gmock等等常用的庫,那么我們使用它們也需要使用異常。

  4. 部分函數(shù)使用異常更好處理,比如構(gòu)造函數(shù)沒有返回值,不方便使用錯(cuò)誤碼方式處理。比如T& operator這樣的函數(shù),如果pos越界了只能使用異?;蛘呓K止程序處理,沒辦法通過返回值表示錯(cuò)誤。

  • C++異常的缺點(diǎn):
  1. 異常會導(dǎo)致程序的執(zhí)行流亂跳,并且非常的混亂,并且是運(yùn)行時(shí)出錯(cuò)拋異常就會亂跳。這會導(dǎo)致我們跟蹤調(diào)試時(shí)以及分析程序時(shí),比較困難。

  2. 異常會有一些性能的開銷。當(dāng)然在現(xiàn)代硬件速度很快的情況下,這個(gè)影響基本忽略不計(jì)。

  3. C++沒有垃圾回收機(jī)制,資源需要自己管理。有了異常非常容易導(dǎo)致內(nèi)存泄漏、死鎖等異常安全問題。這個(gè)需要使用RAII來處理資源的管理問題。學(xué)習(xí)成本較高。

  4. C++標(biāo)準(zhǔn)庫的異常體系定義得不好,導(dǎo)致大家各自定義各自的異常體系,非常的混亂。

  5. 異常盡量規(guī)范使用,否則后果不堪設(shè)想,隨意拋異常,外層捕獲的用戶苦不堪言。所以異常規(guī)范有兩點(diǎn):一、拋出異常類型都繼承自一個(gè)基類。二、函數(shù)是否拋異常、拋什么異常,都使用 func() throw();的方式規(guī)范化。

總結(jié):異??傮w而言,利大于弊,所以工程中我們還是鼓勵(lì)使用異常的。另外OO的語言基本都是用異常處理錯(cuò)誤,這也可以看出這是大勢所趨。


🌹🌹 異常 的知識大概就講到這里啦,博主后續(xù)會繼續(xù)更新更多C++ 和 Linux的相關(guān)知識,干貨滿滿,如果覺得博主寫的還不錯(cuò)的話,希望各位小伙伴不要吝嗇手中的三連哦!你們的支持是博主堅(jiān)持創(chuàng)作的動(dòng)力!💪💪

http://www.risenshineclean.com/news/552.html

相關(guān)文章:

  • 靈璧零度網(wǎng)站建設(shè)/國際新聞最新
  • wordpress 上傳文件中文亂碼/西安搜索引擎優(yōu)化
  • 中企動(dòng)力青島分公司/寧波seo關(guān)鍵詞如何優(yōu)化
  • 中國建設(shè)銀行人力資源網(wǎng)站/營銷互聯(lián)網(wǎng)推廣公司
  • 做站群的網(wǎng)站要備案嗎/電商網(wǎng)站平臺搭建
  • 微信商城與網(wǎng)站一體/谷歌瀏覽器下載手機(jī)版中文
  • 微信推送在哪個(gè)網(wǎng)站做/百度seo排名優(yōu)化技巧分享
  • 聚民網(wǎng)網(wǎng)站建設(shè)/海外網(wǎng)絡(luò)推廣方案
  • 百度云怎么做網(wǎng)站/怎么給網(wǎng)站做優(yōu)化
  • 學(xué)校網(wǎng)站建設(shè)學(xué)生文明上網(wǎng)/下載瀏覽器
  • 網(wǎng)站開發(fā)的需求/今日最新體育新聞
  • 做問卷的網(wǎng)站/一站式推廣平臺
  • 設(shè)計(jì)師可以做兼職的網(wǎng)站/馮耀宗seo
  • 研發(fā)網(wǎng)站要多長時(shí)間/東莞做網(wǎng)站的聯(lián)系電話
  • 安卓app公司開發(fā)/seo站
  • wordpress二維碼用戶登錄/長沙網(wǎng)站優(yōu)化
  • 保定網(wǎng)站優(yōu)化/百seo排名優(yōu)化
  • 域名及密碼登錄域名管理網(wǎng)站/怎么自己找外貿(mào)訂單
  • wordpress開發(fā)視頻網(wǎng)站模板下載/免費(fèi)二級域名平臺
  • 想做一個(gè)自己設(shè)計(jì)公司的網(wǎng)站怎么做/網(wǎng)絡(luò)外包運(yùn)營公司
  • 做鮮花配送網(wǎng)站需要準(zhǔn)備什么/營銷推廣活動(dòng)策劃方案
  • b2c 網(wǎng)站做seo優(yōu)化/蘋果看國外新聞的app
  • 徐州住房和城鄉(xiāng)建設(shè)局網(wǎng)站/互聯(lián)網(wǎng)營銷師證書怎么考
  • 酒店加盟什么網(wǎng)站建設(shè)/百度客服聯(lián)系方式
  • 好的免費(fèi)移動(dòng)網(wǎng)站建設(shè)平臺有哪些/安慶seo
  • 樂清網(wǎng)站推廣公司/seo關(guān)鍵詞排名優(yōu)化怎樣
  • 如何開辦網(wǎng)站/東莞網(wǎng)站推廣策劃
  • 如何做搜索網(wǎng)站/seo外包公司哪家好
  • 大學(xué)社交網(wǎng)站建設(shè)日程表/品牌運(yùn)營推廣方案
  • 青島 公司 網(wǎng)站建設(shè)價(jià)格/網(wǎng)絡(luò)營銷推廣方案范文