亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

c++異常處理機制示例及詳細講解

2020-01-26 15:36:15
字體:
來源:轉載
供稿:網友

這兩天我寫了一個測試c++異常處理機制的例子,感覺有很好的示范作用,在此貼出來,給c++異常處理的初學者入門。本文后附有c++異常的知識普及,有興趣者也可以看看。

下面的代碼直接貼到你的console工程中,可以運行調試看看效果,并分析c++的異常機制。

復制代碼 代碼如下:

#include "stdafx.h"
#include<stdlib.h>
#include<crtdbg.h>
#include <iostream>
// 內存泄露檢測機制
#define _CRTDBG_MAP_ALLOC 
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif

// 自定義異常類
class MyExcepction
{
public:

// 構造函數,參數為錯誤代碼
MyExcepction(int errorId)
{
// 輸出構造函數被調用信息
std::cout << "MyExcepction is called" << std::endl;
m_errorId = errorId;
}

// 拷貝構造函數
MyExcepction( MyExcepction& myExp)
{
// 輸出拷貝構造函數被調用信息
std::cout << "copy construct is called" << std::endl;
this->m_errorId = myExp.m_errorId;
}

~MyExcepction()
{
// 輸出析構函數被調用信息
std::cout << "~MyExcepction is called" << std::endl;
}

// 獲取錯誤碼
int getErrorId()
{
return m_errorId;
}

private: 
// 錯誤碼
int m_errorId;
};

int main(int argc, char* argv[])
{
// 內存泄露檢測機制
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

// 可以改變錯誤碼,以便拋出不同的異常進行測試
int throwErrorCode = 110;

std::cout << " input test code :" << std::endl;
std::cin >> throwErrorCode;

try 
{
if ( throwErrorCode == 110)
{
MyExcepction myStru(110);

// 拋出對象的地址 -> 由catch( MyExcepction* pMyExcepction) 捕獲
// 這里該對象的地址拋出給catch語句,不會調用對象的拷貝構造函數
// 傳地址是提倡的做法,不會頻繁地調用該對象的構造函數或拷貝構造函數
// catch語句執行結束后,myStru會被析構掉
throw &myStru; 
}
else if ( throwErrorCode == 119 )
{
MyExcepction myStru(119);

// 拋出對象,這里會通過拷貝構造函數創建一個臨時的對象傳出給catch
// 由catch( MyExcepction myExcepction) 捕獲
// 在catch語句中會再次調用通過拷貝構造函數創建臨時對象復制這里傳過去的對象
// throw結束后myStru會被析構掉
throw myStru; 
}
else if ( throwErrorCode == 120 )
{
// 不提倡這樣的拋出方法
// 這樣做的話,如果catch( MyExcepction* pMyExcepction)中不執行delete操作則會發生內存泄露

// 由catch( MyExcepction* pMyExcepction) 捕獲
MyExcepction * pMyStru = new MyExcepction(120); 
throw pMyStru; 
}
else 
{
// 直接創建新對象拋出
// 相當于創建了臨時的對象傳遞給了catch語句
// 由catch接收時通過拷貝構造函數再次創建臨時對象接收傳遞過去的對象
// throw結束后兩次創建的臨時對象會被析構掉
throw MyExcepction(throwErrorCode); 

}
catch( MyExcepction* pMyExcepction)
{
// 輸出本語句被執行信息
std::cout << "執行了 catch( MyExcepction* pMyExcepction) " << std::endl;

// 輸出錯誤信息
std::cout << "error Code : " << pMyExcepction->getErrorId()<< std::endl;

// 異常拋出的新對象并非創建在函數棧上,而是創建在專用的異常棧上,不需要進行delete
//delete pMyExcepction;
}
catch ( MyExcepction myExcepction)
{
// 輸出本語句被執行信息
std::cout << "執行了 catch ( MyExcepction myExcepction) " << std::endl;

// 輸出錯誤信息
std::cout << "error Code : " << myExcepction.getErrorId()<< std::endl;
}
catch(...)
{
// 輸出本語句被執行信息
std::cout << "執行了 catch(...) " << std::endl;

// 處理不了,重新拋出給上級
throw ;
}

// 暫停
int temp;
std::cin >> temp;

return 0;


知識點: c++異常機制

一、 概述

C++自身有著非常強的糾錯能力,發展到如今,已經建立了比較完善的異常處理機制。C++的異常情況無非兩種,一種是語法錯誤,即程序中出現了錯誤的語句,函數,結構和類,致使編譯程序無法進行。另一種是運行時發生的錯誤,一般與算法有關。

關于語法錯誤,不必多說,寫代碼時心細一點就可以解決。C++編譯器的報錯機制可以讓我們輕松地解決這些錯誤。

第二種是運行時的錯誤,常見的有文件打開失敗、數組下標溢出、系統內存不足等等。而一旦出現這些問題,引發算法失效、程序運行時無故停止等故障也是常有的。這就要求我們在設計軟件算法時要全面。比如針對文件打開失敗的情況,保護的方法有很多種,最簡單的就是使用“return”命令,告訴上層調用者函數執行失??;另外一種處理策略就是利用c++的異常機制,拋出異常。

二、c++異常處理機制

C++異常處理機制是一個用來有效地處理運行錯誤的非常強大且靈活的工具,它提供了更多的彈性、安全性和穩固性,克服了傳統方法所帶來的問題.

異常的拋出和處理主要使用了以下三個關鍵字: try、 throw 、 catch 。

拋出異常即檢測是否產生異常,在C++中,其采用throw語句來實現,如果檢測到產生異常,則拋出異常。該語句的格式為:
throw 表達式;
如果在try語句塊的程序段中(包括在其中調用的函數)發現了異常,且拋棄了該異常,則這個異常就可以被try語句塊后的某個catch語句所捕獲并處理,捕獲和處理的條件是被拋棄的異常的類型與catch語句的異常類型相匹配。由于C++使用數據類型來區分不同的異常,因此在判斷異常時,throw語句中的表達式的值就沒有實際意義,而表達式的類型就特別重要。

try-catch語句形式如下 :

復制代碼 代碼如下:

try 
{
包含可能拋出異常的語句;
}

catch(類型名 [形參名]) // 捕獲特定類型的異常
{
}
catch(類型名 [形參名]) // 捕獲特定類型的異常
{
}
catch(...) // 三個點則表示捕獲所有類型的異常
{


【范例1】處理除數為0的異常。該范例將上述除數為0的異常可以用try/catch語句來捕獲異常,并使用throw語句來拋出異常,從而實現異常處理,實現代碼如代碼清單1-1所示。
// 代碼清單1-1
復制代碼 代碼如下:

#include<iostream.h> //包含頭文件

#include<stdlib.h>

double fuc(double x, double y) //定義函數
{
if(y==0)
{
throw y; //除數為0,拋出異常
}
return x/y; //否則返回兩個數的商
}
void main()
{
double res;
try //定義異常
{
res=fuc(2,3);
cout<<"The result of x/y is : "<<res<<endl;
res=fuc(4,0); 出現異常,函數內部會拋出異常
}
catch(double) //捕獲并處理異常
{
cerr<<"error of dividing zero./n";
exit(1); //異常退出程序
}


【范例2】自定義異常類型 (在本文開始的代碼中已經給出示范)

三、異常的接口聲明

為了加強程序的可讀性,使函數的用戶能夠方便地知道所使用的函數會拋出哪些異常,可以在函數的聲明中列出這個函數可能拋出的所有異常類型,例如:

void fun() throw( A,B,C,D);

這表明函數fun()可能并且只可能拋出類型(A,B,C,D)及其子類型的異常。

如果在函數的聲明中沒有包括異常的接口聲明,則此函數可以拋出任何類型的異常,例如: void fun();

一個不會拋出任何類型異常的函數可以進行如下形式的聲明:

void fun() thow();

五、異常處理中需要注意的問題

1. 如果拋出的異常一直沒有函數捕獲(catch),則會一直上傳到c++運行系統那里,導致整個程序的終止

2. 一般在異常拋出后資源可以正常被釋放,但注意如果在類的構造函數中拋出異常,系統是不會調用它的析構函數的,處理方法是:如果在構造函數中要拋出異常,則在拋出前要記得刪除申請的資源。

3. 異常處理僅僅通過類型而不是通過值來匹配的,所以catch塊的參數可以沒有參數名稱,只需要參數類型。

4. 函數原型中的異常說明要與實現中的異常說明一致,否則容易引起異常沖突。

5. 應該在throw語句后寫上異常對象時,throw先通過Copy構造函數構造一個新對象,再把該新對象傳遞給 catch. 

那么當異常拋出后新對象如何釋放?
異常處理機制保證:異常拋出的新對象并非創建在函數棧上,而是創建在專用的異常棧上,因此它才可以跨接多個函數而傳遞到上層,否則在棧清空的過程中就會被銷毀。所有從try到throw語句之間構造起來的對象的析構函數將被自動調用。但如果一直上溯到main函數后還沒有找到匹配的catch塊,那么系統調用terminate()終止整個程序,這種情況下不能保證所有局部對象會被正確地銷毀。

6. catch塊的參數推薦采用地址傳遞而不是值傳遞,不僅可以提高效率,還可以利用對象的多態性。另外,派生類的異常撲獲要放到父類異常撲獲的前面,否則,派生類的異常無法被撲獲。

7. 編寫異常說明時,要確保派生類成員函數的異常說明和基類成員函數的異常說明一致,即派生類改寫的虛函數的異常說明至少要和對應的基類虛函數的異常說明相同,甚至更加嚴格,更特殊。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品私拍pans大尺度在线| 18性欧美xxxⅹ性满足| 欧美视频精品一区| 欧美韩国理论所午夜片917电影| 日韩国产精品视频| 亚洲精美色品网站| 日韩欧美中文免费| 亚洲天堂视频在线观看| 国产精品99久久久久久www| 中文字幕少妇一区二区三区| 亚洲奶大毛多的老太婆| 国产精品xxxxx| 日本乱人伦a精品| 精品亚洲va在线va天堂资源站| 日韩在线观看你懂的| 国内外成人免费激情在线视频网站| 亚洲午夜av电影| 欧美黄色片在线观看| xxxxx成人.com| 亚洲欧洲黄色网| 亚洲国产一区自拍| 日韩在线免费观看视频| 亚洲精品国产suv| 亚洲欧美在线播放| 性欧美xxxx交| 国产免费一区视频观看免费| 中文字幕在线精品| 国产精品久久久久99| 亚洲欧美国产日韩天堂区| 久久久噜久噜久久综合| 91大神在线播放精品| 国产精品福利无圣光在线一区| 国产精品毛片a∨一区二区三区|国| 亚洲男人天堂古典| 精品欧美一区二区三区| 国产精品成人观看视频国产奇米| 97精品视频在线播放| 日韩精品极品在线观看播放免费视频| 亚洲人高潮女人毛茸茸| 欧美在线视频在线播放完整版免费观看| 亚洲国产精品va在线| 91沈先生在线观看| 日韩在线观看免费| 国产热re99久久6国产精品| 久久在线观看视频| 国产精品成人播放| 国产亚洲欧美一区| 国产一区二区在线播放| 亚洲一区制服诱惑| 亚洲经典中文字幕| 美女少妇精品视频| 久久国产加勒比精品无码| 成人午夜黄色影院| 亚洲欧美国产精品va在线观看| 欧美第一淫aaasss性| 亚洲精品日韩av| 欧美日韩免费区域视频在线观看| 色综合亚洲精品激情狠狠| 亚洲图片欧洲图片av| 欧美日韩福利电影| 欧美成人小视频| 国产精品女主播| 久久久久成人精品| 精品久久久久久久中文字幕| 国产精品一区二区三区在线播放| 日韩欧美成人网| 久久久999精品视频| 欧美高清第一页| 亚洲系列中文字幕| 国产欧美精品日韩精品| 一区二区欧美亚洲| 亚洲电影免费在线观看| 久久精品视频在线| 国产精品劲爆视频| 日韩精品免费一线在线观看| 亚洲级视频在线观看免费1级| 亚洲色图激情小说| 91社区国产高清| 青草青草久热精品视频在线观看| 91亚洲永久免费精品| 91亚洲精品在线观看| 日韩电影免费在线观看| 92版电视剧仙鹤神针在线观看| 国产精品视频26uuu| 久久亚洲一区二区三区四区五区高| 国产99在线|中文| 国产精品老女人精品视频| 国产精品视频自在线| 欧美亚洲另类激情另类| 欧美性一区二区三区| 国产区亚洲区欧美区| 国产精品高精视频免费| 亚洲影院在线看| 久久久噜噜噜久久中文字免| 久久久亚洲影院你懂的| 九九精品视频在线| 91精品国产乱码久久久久久久久| www国产亚洲精品久久网站| 亚洲综合第一页| 久久久久久久爱| 久久中文字幕一区| 久久亚洲精品视频| 色先锋资源久久综合5566| 国产不卡精品视男人的天堂| 亚洲福利视频网| 色狠狠av一区二区三区香蕉蜜桃| 欧美一级淫片videoshd| 久久电影一区二区| 久久人人爽人人爽人人片av高请| 国产精品劲爆视频| 欧美一级bbbbb性bbbb喷潮片| 中文字幕免费精品一区| 国产97色在线|日韩| 久久影院中文字幕| 蜜臀久久99精品久久久久久宅男| 美女扒开尿口让男人操亚洲视频网站| 国产亚洲一级高清| 久久69精品久久久久久国产越南| 久久久久久综合网天天| 最近2019年中文视频免费在线观看| 91午夜理伦私人影院| 日韩av中文字幕在线免费观看| 亚洲最大福利网| 中文字幕一区日韩电影| 国产精品爽爽爽| 欧美性高潮床叫视频| 国产成人精品优优av| 久久久久久久一区二区| 国产精品男人的天堂| 5252色成人免费视频| 欧美日韩国产限制| 精品五月天久久| 欧美成人黄色小视频| 欧美精品在线第一页| 国产精品麻豆va在线播放| 日韩免费观看视频| 欧美高清视频免费观看| 亚洲日韩第一页| 欧美激情精品久久久久| 欧美午夜激情视频| 中文字幕日韩欧美精品在线观看| 久久这里只有精品99| 中文字幕无线精品亚洲乱码一区| 欧美尺度大的性做爰视频| 欧美黑人性生活视频| 91精品国产免费久久久久久| 成人亚洲激情网| 亚洲国产中文字幕在线观看| 欧美日韩亚洲国产一区| 欧美成人午夜激情在线| 亚洲国产欧美一区二区三区同亚洲| 超碰91人人草人人干| 午夜精品久久久久久久99热| 日韩在线观看精品| 日韩在线观看精品| 91成人在线观看国产| 日韩在线观看高清| 亚洲xxxxx性| 日韩精品有码在线观看| 精品偷拍一区二区三区在线看| 国产主播精品在线| 午夜精品理论片| 国产精品爽爽爽| 久久av在线播放|