簡體   English   中英

帶有和不帶throw()的方法/構造函數簽名中的c ++,用於自定義異常

[英]c++ with and without throw() in method/constructor signature for a custom exception

我是c ++的初學者,因此為這個愚蠢的問題道歉。 我在這里發帖是因為我在stackoverflow上找不到類似的答案。

我正在逐步完成C ++中的異常,而且我正在嘗試使用自定義異常,我有這個代碼

class MyException: public std::exception{
public:
    virtual const char* what() const throw() {
        return "something bad happened";
    }

};

// class that throws above exception

class canGoWrong {
public:
    canGoWrong(){
        throw MyException();
    }
};

上面的代碼由老師展示。 構造函數剛剛實現了基類exception定義的虛函數。 我到那兒。

現在,當我嘗試使用不同版本進行練習時,我嘗試使用自定義函數而不是重新定義虛擬(因為c ++沒有嚴格執行接口的概念,如果我在這里錯了,請糾正我。)

我把它寫成了

class my_custom_shit_exception: public std::exception {
public:
    const char* show() { // I omitted the const throw() here
            return "This is an error encountered\n";
    }
};

class myclass {
public:
    myclass() {
        throw my_custom_shit_exception();
    }
};

總而言之,我沒有發現兩種方式的行為差異

public:
const char* show() {
        return "This is an error encountered\n";
}
virtual const char* what() const throw() {
    return "something bad happened";
}
  • 那么為什么const throw()what()虛函數中使用? 它有什么不同?

謝謝大家。

我想展示Scott Meyers的一些引用

“有效的C ++”第三版

int doSomething() throw(); // note empty exception spec.

這並不是說doSomething永遠不會拋出異常; 它說如果doSomething拋出一個異常,那就是一個嚴重的錯誤,應該調用意外的函數。

有關意外功能的信息,請參閱您最喜歡的搜索引擎或全面的C ++文本。 (您可能會更好地搜索set_unexpected,這是指定意外函數的函數。)

並從“有效的現代C ++”

在C ++ 11中,無條件noexcept用於保證它們不會發出異常的函數。

如果在運行時,異常離開f,則違反了f的異常規范。 使用C ++ 98異常規范,調用堆棧將向f的調用者展開,並且在此處不相關的某些操作之后,程序執行將終止。 使用C ++ 11異常規范,運行時行為略有不同:堆棧只能在程序執行終止之前解除。 展開調用堆棧和可能展開調用堆棧之間的區別對代碼生成產生了驚人的巨大影響。 在noexcept函數中,如果異常將從函數傳播出來,優化器不需要將運行時堆棧保持在不可解除的狀態,也不必確保如果異常離開函數,則以構造的逆序銷毀noexcept函數中的對象。 。 具有“throw()”異常規范的函數缺乏這種優化靈活性,完全沒有異常規范的函數也是如此。

功能簽名

class std::exception {
    //...
public:
    virtual const char* what() const throw();
    //...
};

可以理解為: whatstd::exception的虛擬成員函數,它返回一個指向常量字符(數組)的指針,並且不修改該對象的成員(因此是第二個const ),並保證不拋出異常在其代碼中。

請注意,異常規范現在已被棄用:相反,從C ++ 11開始,有noexcept說明符來聲明“保證”不拋出異常的函數。 另外,從C ++ 17開始, throw()已成為noexcept(true)的同義詞,但行為略有不同。

有關更多詳細信息,請參閱noexcept 此說明

它還說:“請注意,函數的noexcept規范不是編譯時檢查;它只是程序員通知編譯器函數是否應該拋出異常的方法。編譯器可以使用此信息來對非投擲函數啟用某些優化[...]“。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM