最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解析C++編程中異常相關(guān)的堆棧展開(kāi)和throw()異常規(guī)范

 更新時(shí)間:2016年01月25日 17:38:25   投稿:goldensun  
這篇文章主要介紹了C++編程中異常相關(guān)的堆棧展開(kāi)和throw()異常規(guī)范,throw()規(guī)范部分文中結(jié)合了C++11標(biāo)準(zhǔn)的新特性來(lái)講,需要的朋友可以參考下

C++ 中的異常和堆棧展開(kāi)
在 C++ 異常機(jī)制中,控制從 throw 語(yǔ)句移至可處理引發(fā)類(lèi)型的第一個(gè) catch 語(yǔ)句。在到達(dá) catch 語(yǔ)句時(shí),throw 語(yǔ)句和 catch 語(yǔ)句之間的范圍內(nèi)的所有自動(dòng)變量將在名為“堆棧展開(kāi)”的過(guò)程中被銷(xiāo)毀。在堆棧展開(kāi)中,執(zhí)行將繼續(xù),如下所示:
控制通過(guò)正常順序執(zhí)行到達(dá) try 語(yǔ)句。執(zhí)行 try 塊內(nèi)的受保護(hù)部分。
如果執(zhí)行受保護(hù)的部分的過(guò)程中未引發(fā)異常,將不會(huì)執(zhí)行 try 塊后面的 catch 子句。執(zhí)行將在關(guān)聯(lián)的 try 塊后的最后一個(gè) catch 子句后面的語(yǔ)句上繼續(xù)。
如果執(zhí)行受保護(hù)部分的過(guò)程中或在受保護(hù)的部分調(diào)用的任何例程中引發(fā)異常(直接或間接),則從通過(guò) throw 操作數(shù)創(chuàng)建的對(duì)象中創(chuàng)建異常對(duì)象。(這意味著,可能會(huì)涉及復(fù)制構(gòu)造函數(shù)。)此時(shí),編譯器會(huì)在權(quán)限更高的執(zhí)行上下文中查找可處理引發(fā)的類(lèi)型異常的 catch 子句,或查找可以處理任何類(lèi)型的異常的 catch 處理程序。按照 catch 處理程序在 try 塊后面的顯示順序檢查這些處理程序。如果未找到適當(dāng)?shù)奶幚沓绦?,則檢查下一個(gè)動(dòng)態(tài)封閉的 try 塊。此過(guò)程將繼續(xù),直到檢查最外面的封閉 try 塊。
如果仍未找到匹配的處理程序,或者在展開(kāi)過(guò)程中但在處理程序獲得控制前發(fā)生異常,則調(diào)用預(yù)定義的運(yùn)行時(shí)函數(shù) terminate。如果在引發(fā)異常后但在展開(kāi)開(kāi)始前發(fā)生異常,則調(diào)用 terminate。
如果找到匹配的 catch 處理程序,并且它通過(guò)值進(jìn)行捕獲,則通過(guò)復(fù)制異常對(duì)象來(lái)初始化其形參。如果它通過(guò)引用進(jìn)行捕獲,則初始化參數(shù)以引用異常對(duì)象。在初始化形參后,堆棧的展開(kāi)過(guò)程將開(kāi)始。這包括對(duì)與 catch 處理程序關(guān)聯(lián)的 try 塊的開(kāi)頭和異常的引發(fā)站點(diǎn)之間完全構(gòu)造(但尚未析構(gòu))的所有自動(dòng)對(duì)象的析構(gòu)。析構(gòu)按照與構(gòu)造相反的順序發(fā)生。執(zhí)行 catch 處理程序且程序會(huì)在最后一個(gè)處理程序之后(即,在不是 catch 處理程序的第一個(gè)語(yǔ)句或構(gòu)造處)恢復(fù)執(zhí)行??刂浦荒芡ㄟ^(guò)引發(fā)的異常進(jìn)入 catch 處理程序,而絕不會(huì)通過(guò) goto 語(yǔ)句或 switch 語(yǔ)句中的 case 標(biāo)簽進(jìn)入。
堆棧展開(kāi)示例
以下示例演示引發(fā)異常時(shí)如何展開(kāi)堆棧。線程執(zhí)行將從 C 中的 throw 語(yǔ)句跳轉(zhuǎn)到 main 中的 catch 語(yǔ)句,并在此過(guò)程中展開(kāi)每個(gè)函數(shù)。請(qǐng)注意創(chuàng)建 Dummy 對(duì)象的順序,并且會(huì)在它們超出范圍時(shí)將其銷(xiāo)毀。還請(qǐng)注意,除了包含 catch 語(yǔ)句的 main 之外,其他函數(shù)均未完成。函數(shù) A 絕不會(huì)從其對(duì) B() 的調(diào)用返回,并且 B 絕不會(huì)從其對(duì) C() 的調(diào)用返回。如果取消注釋 Dummy 指針和相應(yīng)的 delete 語(yǔ)句的定義并運(yùn)行程序,請(qǐng)注意絕不會(huì)刪除該指針。這說(shuō)明了當(dāng)函數(shù)不提供異常保證時(shí)會(huì)發(fā)生的情況。有關(guān)詳細(xì)信息,請(qǐng)參閱“如何:針對(duì)異常進(jìn)行設(shè)計(jì)”。如果注釋掉 catch 語(yǔ)句,則可以觀察當(dāng)程序因未經(jīng)處理的異常而終止時(shí)將發(fā)生的情況。

#include <string>
#include <iostream>
using namespace std;

class MyException{};
class Dummy
{
 public:
 Dummy(string s) : MyName(s) { PrintMsg("Created Dummy:"); }
 Dummy(const Dummy& other) : MyName(other.MyName){ PrintMsg("Copy created Dummy:"); }
 ~Dummy(){ PrintMsg("Destroyed Dummy:"); }
 void PrintMsg(string s) { cout << s << MyName << endl; }
 string MyName; 
 int level;
};


void C(Dummy d, int i)
{ 
 cout << "Entering FunctionC" << endl;
 d.MyName = " C";
 throw MyException(); 

 cout << "Exiting FunctionC" << endl;
}

void B(Dummy d, int i)
{
 cout << "Entering FunctionB" << endl;
 d.MyName = "B";
 C(d, i + 1); 
 cout << "Exiting FunctionB" << endl; 
}

void A(Dummy d, int i)
{ 
 cout << "Entering FunctionA" << endl;
 d.MyName = " A" ;
 // Dummy* pd = new Dummy("new Dummy"); //Not exception safe!!!
 B(d, i + 1);
 // delete pd; 
 cout << "Exiting FunctionA" << endl; 
}


int main()
{
 cout << "Entering main" << endl;
 try
 {
  Dummy d(" M");
  A(d,1);
 }
 catch (MyException& e)
 {
  cout << "Caught an exception of type: " << typeid(e).name() << endl;
 }

 cout << "Exiting main." << endl;
 char c;
 cin >> c;
}


輸出:
 Entering main
 Created Dummy: M
 Copy created Dummy: M
 Entering FunctionA
 Copy created Dummy: A
 Entering FunctionB
 Copy created Dummy: B
 Entering FunctionC
 Destroyed Dummy: C
 Destroyed Dummy: B
 Destroyed Dummy: A
 Destroyed Dummy: M
 Caught an exception of type: class MyException
 Exiting main.



異常規(guī)范 (throw)
異常規(guī)范是在 C++11 中棄用的 C++ 語(yǔ)言功能。這些規(guī)范原本用來(lái)提供有關(guān)可從函數(shù)引發(fā)哪些異常的摘要信息,但在實(shí)際應(yīng)用中發(fā)現(xiàn)這些規(guī)范存在問(wèn)題。證明確實(shí)有一定用處的一個(gè)異常規(guī)范是 throw() 規(guī)范。例如:


void MyFunction(int i) throw();

告訴編譯器函數(shù)不引發(fā)任何異常。它相當(dāng)于使用 __declspec(nothrow)。這種用法是可選的。
(C++11) 在 ISO C++11 標(biāo)準(zhǔn)中,引入了 noexcept 運(yùn)算符,該運(yùn)算符在 Visual Studio 2015 及更高版本中受支持。盡可能使用 noexcept 指定函數(shù)是否可能會(huì)引發(fā)異常。
Visual C++ 中實(shí)現(xiàn)的異常規(guī)范與 ISO C++ 標(biāo)準(zhǔn)有所不同。下表總結(jié)了 Visual C++ 的異常規(guī)范實(shí)現(xiàn):

異常規(guī)范 含義
throw() 函數(shù)不會(huì)引發(fā)異常。但是,如果從標(biāo)記為 throw() 函數(shù)引發(fā)異常,Visual C++ 編譯器將不會(huì)調(diào)用意外處理函數(shù)。如果使用 throw() 標(biāo)記一個(gè)函數(shù),則 Visual C++ 編譯器假定該函數(shù)不會(huì)引發(fā) C++ 異常,并相應(yīng)地生成代碼。由于 C++ 編譯器可能會(huì)執(zhí)行代碼優(yōu)化(基于函數(shù)不會(huì)引發(fā)任何 C++ 異常的假設(shè)),因此,如果函數(shù)引發(fā)異常,則程序可能無(wú)法正確執(zhí)行。
throw(...) 函數(shù)可以引發(fā)異常。
throw(type) 函數(shù)可以引發(fā) type 類(lèi)型的異常。但是,在 Visual C++ .NET 中,這被解釋為 throw(...)。

如果在應(yīng)用程序中使用異常處理,則一定有一個(gè)或多個(gè)函數(shù)處理引發(fā)的異常。在引發(fā)異常的函數(shù)和處理異常的函數(shù)間調(diào)用的所有函數(shù)必須能夠引發(fā)異常。
函數(shù)的引發(fā)行為基于以下因素:

  • 您是否在 C 或 C++ 下編譯函數(shù)。
  • 您所使用的 /EH 編譯器選項(xiàng)。
  • 是否顯式指定異常規(guī)范。

不允許對(duì) C 函數(shù)使用顯式異常規(guī)范。

下表總結(jié)了函數(shù)的引發(fā)行為:

2016125173453469.png (697×254)

// exception_specification.cpp
// compile with: /EHs
#include <stdio.h>

void handler() {
 printf_s("in handler\n");
}

void f1(void) throw(int) {
 printf_s("About to throw 1\n");
 if (1)
  throw 1;
}

void f5(void) throw() {
 try {
  f1();
 }
 catch(...) {
  handler();
 }
}

// invalid, doesn't handle the int exception thrown from f1()
// void f3(void) throw() {
// f1();
// }

void __declspec(nothrow) f2(void) {
 try {
  f1();
 }
 catch(int) {
  handler();
 }
}

// only valid if compiled without /EHc 
// /EHc means assume extern "C" functions don't throw exceptions
extern "C" void f4(void);
void f4(void) {
 f1();
}

int main() {
 f2();

 try {
  f4();
 }
 catch(...) {
  printf_s("Caught exception from f4\n");
 }
 f5();
}

輸出:

About to throw 1
in handler
About to throw 1
Caught exception from f4
About to throw 1
in handler

相關(guān)文章

  • C++編寫(xiě)非侵入式接口

    C++編寫(xiě)非侵入式接口

    這篇文章主要介紹了C++編寫(xiě)非侵入式接口的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • C++非遞歸隊(duì)列實(shí)現(xiàn)二叉樹(shù)的廣度優(yōu)先遍歷

    C++非遞歸隊(duì)列實(shí)現(xiàn)二叉樹(shù)的廣度優(yōu)先遍歷

    這篇文章主要介紹了C++非遞歸隊(duì)列實(shí)現(xiàn)二叉樹(shù)的廣度優(yōu)先遍歷,實(shí)例分析了遍歷二叉樹(shù)相關(guān)算法技巧,并附帶了兩個(gè)相關(guān)算法實(shí)例,需要的朋友可以參考下
    2015-07-07
  • C++中perror和fprintf區(qū)別解析

    C++中perror和fprintf區(qū)別解析

    本文主要對(duì)比了C語(yǔ)言中的兩個(gè)函數(shù)perror和fprintf的區(qū)別,perror主要用于輸出與系統(tǒng)錯(cuò)誤相關(guān)的消息,根據(jù)全局變量errno的值生成錯(cuò)誤信息,而fprintf則用于格式化輸出任意類(lèi)型的信息到指定的文件流
    2024-10-10
  • c語(yǔ)言中單引號(hào)和雙引號(hào)的區(qū)別(順利解決從字符串中提取IP地址的困惑)

    c語(yǔ)言中單引號(hào)和雙引號(hào)的區(qū)別(順利解決從字符串中提取IP地址的困惑)

    c語(yǔ)言中的單引號(hào)和雙引號(hào)可是有很大區(qū)別的,使用之前一定要了解他們之間到底有什么不同,下面小編就給大家詳細(xì)的介紹一下吧,對(duì)此還不是很了解的朋友可以過(guò)來(lái)參考下
    2013-07-07
  • VS2010+Opencv+MFC讀取圖像和視頻顯示在Picture控件

    VS2010+Opencv+MFC讀取圖像和視頻顯示在Picture控件

    這篇文章主要為大家詳細(xì)介紹了VS2010+Opencv+MFC讀取圖像和視頻顯示在Picture控件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • C++?解決求兩個(gè)鏈表的第一個(gè)公共結(jié)點(diǎn)問(wèn)題

    C++?解決求兩個(gè)鏈表的第一個(gè)公共結(jié)點(diǎn)問(wèn)題

    本文主要介紹了利用C++實(shí)現(xiàn)輸入兩個(gè)無(wú)環(huán)的單向鏈表時(shí),找出它們的第一個(gè)公共結(jié)點(diǎn)的問(wèn)題。文章中的示例代碼簡(jiǎn)潔易懂,感興趣的同學(xué)可以和小編一起學(xué)習(xí)一下
    2021-12-12
  • VSCode之CMake使用小結(jié)

    VSCode之CMake使用小結(jié)

    本文主要介紹了VSCode之CMake使用小結(jié),文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-03-03
  • c++ STL庫(kù)容器之集合set代碼實(shí)例

    c++ STL庫(kù)容器之集合set代碼實(shí)例

    在本篇文章里小編給大家整理的是關(guān)于c++STL庫(kù)容器之集合set代碼實(shí)例,需要的朋友們可以參考下。
    2020-03-03
  • C++學(xué)習(xí)之Lambda表達(dá)式的用法詳解

    C++學(xué)習(xí)之Lambda表達(dá)式的用法詳解

    Lambda?表達(dá)式(lambda?expression)是一個(gè)匿名函數(shù),Lambda表達(dá)式基于數(shù)學(xué)中的λ演算得名。本文就來(lái)為大家詳細(xì)講講C++中Lambda表達(dá)式的使用,需要的可以參考一下
    2022-07-07
  • C++ 風(fēng)靡一時(shí)的連連看游戲的實(shí)現(xiàn)流程詳解

    C++ 風(fēng)靡一時(shí)的連連看游戲的實(shí)現(xiàn)流程詳解

    游戲“連連看”是源自臺(tái)灣的桌面小游戲,自從流入大陸以來(lái)風(fēng)靡一時(shí),也吸引眾多程序員開(kāi)發(fā)出多種版本的“連連看”。這其中,顧芳編寫(xiě)的“阿達(dá)連連看”以其精良的制作廣受好評(píng),這也成為顧方“阿達(dá)系列軟件”的核心產(chǎn)品。并于2004年,取得國(guó)家版權(quán)局的計(jì)算機(jī)軟件登記證書(shū)
    2021-11-11

最新評(píng)論

庐江县| 乐业县| 兰州市| 扎兰屯市| 桐梓县| 启东市| 屏东市| 绵阳市| 衡水市| 山东省| 休宁县| 永善县| 霍城县| 襄城县| 常宁市| 平武县| 施甸县| 台东县| 曲周县| 锡林浩特市| 文水县| 满洲里市| 额尔古纳市| 会同县| 镇平县| 黄山市| 莎车县| 普安县| 莱州市| 大同县| 丹巴县| 稷山县| 花垣县| 伊吾县| 拜泉县| 镇雄县| 天台县| 凤翔县| 晋江市| 马尔康县| 平顶山市|