2017年計算機二級C++實例編程:c++異常處理機制示例及講解

字號:


    c++異常處理機制示例及講解
    下面的代碼直接貼到你的console工程中,可以運行調(diào)試看看效果,并分析c++的異常機制。
    #include "stdafx.h"
    #include
    #include
    #include
    // 內(nèi)存泄露檢測機制
    #define _CRTDBG_MAP_ALLOC
    #ifdef _DEBUG
    #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
    #endif
    // 自定義異常類
    class MyExcepction
    {
    public:
    // 構(gòu)造函數(shù),參數(shù)為錯誤代碼
    MyExcepction(int errorId)
    {
    // 輸出構(gòu)造函數(shù)被調(diào)用信息
    std::cout << "MyExcepction is called" << std::endl;
    m_errorId = errorId;
    }
    // 拷貝構(gòu)造函數(shù)
    MyExcepction( MyExcepction& myExp)
    {
    // 輸出拷貝構(gòu)造函數(shù)被調(diào)用信息
    std::cout << "copy construct is called" << std::endl;
    this->m_errorId = myExp.m_errorId;
    }
    ~MyExcepction()
    {
    // 輸出析構(gòu)函數(shù)被調(diào)用信息
    std::cout << "~MyExcepction is called" << std::endl;
    }
    // 獲取錯誤碼
    int getErrorId()
    {
    return m_errorId;
    }
    private:
    // 錯誤碼
    int m_errorId;
    };
    int main(int argc, char* argv[])
    {
    // 內(nèi)存泄露檢測機制
    _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語句,不會調(diào)用對象的拷貝構(gòu)造函數(shù)
    // 傳地址是提倡的做法,不會頻繁地調(diào)用該對象的構(gòu)造函數(shù)或拷貝構(gòu)造函數(shù)
    // catch語句執(zhí)行結(jié)束后,myStru會被析構(gòu)掉
    throw &myStru;
    }
    else if ( throwErrorCode == 119 )
    {
    MyExcepction myStru(119);
    // 拋出對象,這里會通過拷貝構(gòu)造函數(shù)創(chuàng)建一個臨時的對象傳出給catch
    // 由catch( MyExcepction myExcepction) 捕獲
    // 在catch語句中會再次調(diào)用通過拷貝構(gòu)造函數(shù)創(chuàng)建臨時對象復(fù)制這里傳過去的對象
    // throw結(jié)束后myStru會被析構(gòu)掉
    throw myStru;
    }
    else if ( throwErrorCode == 120 )
    {
    // 不提倡這樣的拋出方法
    // 這樣做的話,如果catch( MyExcepction* pMyExcepction)中不執(zhí)行delete操作則會發(fā)生內(nèi)存泄露
    // 由catch( MyExcepction* pMyExcepction) 捕獲
    MyExcepction * pMyStru = new MyExcepction(120);
    throw pMyStru;
    }
    else
    {
    // 直接創(chuàng)建新對象拋出
    // 相當(dāng)于創(chuàng)建了臨時的對象傳遞給了catch語句
    // 由catch接收時通過拷貝構(gòu)造函數(shù)再次創(chuàng)建臨時對象接收傳遞過去的對象
    // throw結(jié)束后兩次創(chuàng)建的臨時對象會被析構(gòu)掉
    throw MyExcepction(throwErrorCode);
    }
    }
    catch( MyExcepction* pMyExcepction)
    {
    // 輸出本語句被執(zhí)行信息
    std::cout << "執(zhí)行了 catch( MyExcepction* pMyExcepction) " << std::endl;
    // 輸出錯誤信息
    std::cout << "error Code : " << pMyExcepction->getErrorId()<< std::endl;
    // 異常拋出的新對象并非創(chuàng)建在函數(shù)棧上,而是創(chuàng)建在專用的異常棧上,不需要進行delete
    //delete pMyExcepction;
    }
    catch ( MyExcepction myExcepction)
    {
    // 輸出本語句被執(zhí)行信息
    std::cout << "執(zhí)行了 catch ( MyExcepction myExcepction) " << std::endl;
    // 輸出錯誤信息
    std::cout << "error Code : " << myExcepction.getErrorId()<< std::endl;
    }
    catch(...)
    {
    // 輸出本語句被執(zhí)行信息
    std::cout << "執(zhí)行了 catch(...) " << std::endl;
    // 處理不了,重新拋出給上級
    throw ;
    }
    // 暫停
    int temp;
    std::cin >> temp;
    return 0;
    }