1. 程式人生 > 實用技巧 >異常型別變數的生命週期

異常型別變數的生命週期

傳統的錯誤處理機制:

#include<iostream>
using namespace std;

//傳統的處理機制
int my_strcopy(char* from, char* to)
{
    if (from == NULL)
        return 1;
    if (to == NULL)
        return 2;

    //拷貝場景檢查
    if (*from == 'a')
        return 3;
    while (*from != '\0')
    {
        *to = *from;
        to ++;
        
from ++; } *to = '\0'; return 0; } int main() { int ret = 0; char buf1[] = "abcdefg"; char buf2[1024] = { 0 }; ret = my_strcopy(buf1, buf2); if (ret != 0) { switch (ret) { case 1: cout << "源buf出錯!" << endl; break
; case 2: cout << "目的buf出錯!" << endl; case 3: cout << "拷貝過程出錯!" << endl; default: cout << "未知錯誤" << endl; break; } } cout << "buf2 = " << buf2 << endl; system(
"pause"); return 0; }

用異常解決:

#include<iostream>
using namespace std;

//傳統的處理機制
//throw int 型別異常
void my_strcopy2(char* from, char* to)
{
    if (from == NULL)
        throw 1;
    if (to == NULL)
        throw 2;

    //拷貝場景檢查
    if (*from == 'a')
        throw 3;
    while (*from != '\0')
    {
        *to = *from;
        to ++;
        from ++;
    }
    *to = '\0';
}
//throw char 型別異常
void my_strcopy1(char* from, char* to)
{
    if (from == NULL)
        throw "源buf出錯";
    if (to == NULL)
        throw "目的buf出錯";

    //拷貝場景檢查
    if (*from == 'a')
        throw "copy時出錯";
    while (*from != '\0')
    {
        *to = *from;
        to++;
        from++;
    }
    *to = '\0';
}
class BadSrcType{};
class BadDestType{};
class BadProcessType{};
//throw 類物件型別異常
void my_strcopy3(char* from, char* to)
{
    if (from == NULL)
        throw BadSrcType(); //會不會產生匿名物件
    if (to == NULL)
        throw BadDestType();

    //拷貝場景檢查
    if (*from == 'a')
        throw BadProcessType();
    while (*from != '\0')
    {
        *to = *from;
        to++;
        from++;
    }
    *to = '\0';
}
int main()
{
    int ret = 0;
    char buf1[] = "abcdefg";
    char buf2[1024] = { 0 };

    try
    {
        my_strcopy3(buf1, buf2);
    }
    catch (int e )//變數名可以寫可以不寫
    {
        cout << "int型別異常" << endl;
    }
    catch (char *e)
    {
        cout << e << "char*型別異常" << endl;
    }
    //---
    catch (BadSrcType e)//是把匿名物件拷貝給e,還是e直接就是匿名物件
    {
        cout << "BadSrcType型別異常" << endl;
    }
    catch (BadDestType e)
    {
        cout << "BadDestType型別異常" << endl;
    }
    catch (BadProcessType e)
    {
        cout << "BadProcessType型別異常" << endl;
    }
    //--
    catch (...)
    {
        cout << "未知異常 " << endl;
    }
    system("pause");
    return 0;
    
}

接下來解決程式碼中提出的問題:

    catch (BadSrcType e)//是把匿名物件拷貝給e,還是e直接就是匿名物件

先新增完類的定義:
class BadProcessType
{
public:
    BadProcessType()
    {
        cout << "BadProcessType建構函式do \n";
    }
    BadProcessType(const BadProcessType& obj)
    {
        cout << "BadProcessType拷貝建構函式do \n";
    }

    ~BadProcessType()
    {
        cout << "BadProcessType解構函式do \n";
    }
};

結論1:如果 接受異常的時候,使用一個異常變數,則拷貝構造異常變數

接下來測試引用:

    catch (BadProcessType &e)
    {
        cout << "BadProcessType型別異常" << endl;
    }

沒有拷貝新的變數

結論2:如果使用引用,會使用throw的那個物件

下面測試指標:

    catch (BadProcessType &e)
    {
        cout << "BadProcessType型別異常" << endl;
    }
    catch (BadProcessType* e)
    {
        cout << "BadProcessType型別異常" << endl;
    }

結論3:指標可以和引用和元素寫在一塊,但是元素和引用不能寫在一塊

此時丟擲異常時應該丟擲地址:

    if (*from == 'b')
        throw& (BadProcessType());

此時因為解構函式已經完成,指標變成了野指標。

所以指標應當這樣丟擲:

    if (*from == 'c')
        throw new BadProcessType;
    catch (BadProcessType* e)
    {
        cout << "BadProcessType地址型別異常" << endl;
        delete e;
    }

略煩,所以最好選擇引用來抓取異常。所有操作都自動處理。