簡體   English   中英

不確定何時在C ++中使用異常

[英]Not sure when to use exceptions in C++

經過多年用C ++編寫科學軟件的代碼,我似乎還不習慣異常,我不知道何時應該使用它們。 我知道使用它們來控制程序流是一個很大的禁忌,但除此之外......請考慮以下示例(摘自表示圖像蒙版的類,並允許用戶將區域添加為多邊形):

class ImageMask
{
public:
    ImageMask() {}
    ImageMask(const Size2DI &imgSize);

    void addPolygon(const PolygonI &polygon);

protected:
    Size2DI imgSize_;
    std::vector<PolygonI> polygons_;
};

此類的默認構造函數創建一個無用的實例,其圖像大小未定義。 我不希望用戶能夠將多邊形添加到這樣的對象。 但我不知道如何處理這種情況。 當大小未定義,並調用addPolygon()時,我應該:

  1. 默默地回來,
  2. 斷言(imgSize_.valid)以使用此類檢測代碼中的違規並在發布之前修復它們,
  3. 拋出異常?

大部分時間我都會選擇1)或2)(取決於我的心情),因為在我看來,例外是昂貴的,混亂的,並且對於這樣一個簡單的場景來說簡直太過分了。 請問有些見解?

一般規則是當您無法執行所需操作時拋出異常。 所以在你的情況下,是的,當調用addPolygon並且大小未定義或不一致時拋出異常是有意義的。

悄悄回歸幾乎總是錯誤的做法。 assert不是一個好的錯誤處理技術(它更像是一種設計/文檔技術)。

但是,在您的情況下,重新設計界面以使錯誤條件不可能或不太可能更好。 例如,像這樣:

class ImageMask
{
public:
    // Constructor requires collection of polygons and size.
    // Neither can be changed after construction.
    ImageMask(std::vector<PolygonI>& polygons, size_t size);
}

或者像這樣

class ImageMask
{
public:
    class Builder
    {
    public:
        Builder();
        void addPolygon();
    };

    ImageMask(const Builder& builder);
}

// used like this
ImageMask::Builder builder;
builder.addPolygon(polyA);
builder.addPolygon(polyB);
ImageMask mask(builder);

我會盡量避免任何可能創建處於某種無用狀態的數據的情況。 如果你需要一個非空的多邊形,那么不要讓空的多邊形被創建,你可以省去很多麻煩,因為編譯器會強制沒有空的多邊形。

我從不使用靜默返回,因為它們隱藏了錯誤,這使得發現錯誤比它必須復雜得多。

當我檢測到程序處於只能進入的狀態時,如果軟件中存在錯誤,我會使用斷言。 在您的示例中,如果您檢查帶有Size2DI的c'tor,該大小不為空,而不是斷言存儲的大小是否為空,對於檢測錯誤很有用。 斷言不應該有副作用,必須可以刪除它們,而不改變軟件的行為。 我發現它們非常有用,可以找到我自己的bug和文檔,對象/函數的當前狀態等。

如果很可能,一個函數的調用者將直接處理運行時錯誤,我會使用傳統的返回值。 如果很可能,這個錯誤情況必須通過調用堆棧的幾個函數調用進行通信,我更喜歡異常。 有疑問我提供兩個功能。

親切的問候托斯滕

對我來說,1是無選擇。 無論是2還是3,取決於程序/庫的設計,是否考慮(和文檔)默認構建圖像蒙版,然后添加多邊形對組件的有效或無效使用。 這是一個重要的設計決策。 我建議閱讀馬修威爾遜的這篇文章

請注意,您有更多選擇:

  • 創建自己的斷言,始終調用std :: terminate並執行其他日志記錄
  • 禁用默認構造函數(正如其他人已經指出的那樣) - 這是我的最愛
  1. “默默回歸” - 這是真正的“大禁忌”。 該程序應該知道什么是錯的。
  2. “斷言” - 第二條規則是僅在正常程序的流程無法恢復時斷言。
  3. “扔異常” - 是的,這是正確而好的技巧。 只需要注意異常安全。 關於GotW的異常安全編碼有很多文章。

不要害怕例外。 他們不咬人。 :)如果你能夠充分利用這項技術,那么你將成為一名強大的程序員。 ;)

暫無
暫無

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

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