第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么應(yīng)該保守地使用例外?

為什么應(yīng)該保守地使用例外?

C++
慕虎7371278 2019-12-10 13:08:35
我經(jīng)常看到/聽到人們說例外情況應(yīng)該很少使用,而永遠不要解釋原因。盡管這可能是正確的,但基本原理通常是一個輕浮的說法:“由于某種原因,它被稱為例外”,對我而言,這似乎是一種受尊敬的程序員/工程師不應(yīng)接受的解釋??梢允褂卯惓=鉀Q一系列問題。為什么將它們用于控制流是不明智的?對它們的使用格外保守的背后的哲學(xué)是什么?語義學(xué)?性能?復(fù)雜?美學(xué)?慣例?我以前看過一些性能分析,但分析的水平與某些系統(tǒng)相關(guān),而與其他系統(tǒng)無關(guān)。同樣,我不一定不同意在特殊情況下應(yīng)該保存它們,但是我想知道共識的基礎(chǔ)是什么(如果存在這種情況)。
查看完整描述

3 回答

?
當(dāng)年話下

TA貢獻1890條經(jīng)驗 獲得超9個贊

盡管“在特殊情況下拋出異?!笔且粋€很好的答案,但您實際上可以定義這些情況是什么:當(dāng)滿足先決條件而不能滿足后置條件時。這使您可以編寫更嚴格,更嚴格和更有用的后置條件,而無需犧牲錯誤處理;否則,您必須毫無例外地更改后置條件,以允許所有可能的錯誤狀態(tài)。


調(diào)用函數(shù)之前,前提條件必須為true 。

后置條件是功能保證什么之后就返回。

異常安全性說明異常如何影響函數(shù)或數(shù)據(jù)結(jié)構(gòu)的內(nèi)部一致性,并經(jīng)常處理從外部傳入的行為(例如函子,模板參數(shù)的ctor等)。

建設(shè)者

關(guān)于可以用C ++編寫的每個類的每個構(gòu)造函數(shù),您幾乎沒有什么要說的,但是有幾件事。其中最主要的是構(gòu)造的對象(即構(gòu)造函數(shù)返回成功的對象)將被破壞。 您無法修改此后置條件,因為該語言假定該條件是正確的,并將自動調(diào)用析構(gòu)函數(shù)。 (從技術(shù)上講,您可以接受未定義行為的可能性,該語言對此不作任何保證,但這在其他地方可能會更好地涵蓋。)


當(dāng)構(gòu)造函數(shù)無法成功時引發(fā)異常的唯一替代方法是修改類的基本定義(“類不變”)以允許有效的“ null”或僵尸狀態(tài),從而允許構(gòu)造函數(shù)通過構(gòu)造僵尸來“成功” 。


僵尸的例子

這種僵尸修改的示例是std :: ifstream,您必須始終檢查其狀態(tài)才能使用它。例如,因為std :: string不存在,所以始終保證您可以在構(gòu)造后立即使用它。想象一下,如果您必須編寫如本例所示的代碼,并且如果忘記了檢查僵尸狀態(tài),那么您要么默默地得到不正確的結(jié)果,要么會破壞程序的其他部分:


string s = "abc";

if (s.memory_allocation_succeeded()) {

  do_something_with(s); // etc.

}

甚至命名該方法也是一個很好的例子,說明如何必須為情況字符串修改類的不變式和接口,而無法預(yù)測或處理自身。


驗證輸入示例

我們來看一個常見的例子:驗證用戶輸入。僅僅因為我們要允許失敗的輸入并不意味著解析函數(shù)需要在其后置條件中包括該內(nèi)容。但是,這確實意味著我們的處理程序需要檢查解析器是否失敗。


// boost::lexical_cast<int>() is the parsing function here

void show_square() {

  using namespace std;

  assert(cin); // precondition for show_square()

  cout << "Enter a number: ";

  string line;

  if (!getline(cin, line)) { // EOF on cin

    // error handling omitted, that EOF will not be reached is considered

    // part of the precondition for this function for the sake of example

    //

    // note: the below Python version throws an EOFError from raw_input

    //  in this case, and handling this situation is the only difference

    //  between the two

  }

  int n;

  try {

    n = boost::lexical_cast<int>(line);

    // lexical_cast returns an int

    // if line == "abc", it obviously cannot meet that postcondition

  }

  catch (boost::bad_lexical_cast&) {

    cout << "I can't do that, Dave.\n";

    return;

  }

  cout << n * n << '\n';

}

不幸的是,這顯示了兩個示例,這些示例說明C ++的作用域如何要求您破壞RAII / SBRM。Python中沒有這個問題的示例,顯示了我希望C ++擁有的一些東西– try-else:


# int() is the parsing "function" here

def show_square():

  line = raw_input("Enter a number: ") # same precondition as above

  # however, here raw_input will throw an exception instead of us

  # using assert

  try:

    n = int(line)

  except ValueError:

    print "I can't do that, Dave."

  else:

    print n * n

前提條件

前提條件不必嚴格檢查-違反前提條件總是表示邏輯失敗,這是調(diào)用方的責(zé)任-但如果您檢查了前提條件,則拋出異常是適當(dāng)?shù)?。(在某些情況下,返回垃圾或使程序崩潰更合適;盡管這些動作在其他情況下可能是非常錯誤的。如何最好地處理未定義的行為是另一個主題。)


特別是,請對比一下stdlib異常層次結(jié)構(gòu)的std :: logic_error和std :: runtime_error分支。前者通常用于違反先決條件,而后者更適合于違反先決條件。



查看完整回答
反對 回復(fù) 2019-12-11
?
MYYA

TA貢獻1868條經(jīng)驗 獲得超4個贊

  1. 昂貴的 
    內(nèi)核調(diào)用(或其他系統(tǒng)API調(diào)用)來管理內(nèi)核(系統(tǒng))信號接口

  2. 難以分析語句中的
    許多問題都goto適用于異常。它們經(jīng)常跳過多個例程和源文件中潛在的大量代碼。通過閱讀中間源代碼,這并不總是顯而易見的。(使用Java。)

  3. 中間代碼并不總能預(yù)料
    到被跳過的代碼在編寫或未編寫時都會考慮到異常退出的可能性。如果最初是這樣寫的,那么可能不會考慮到這一點。想一想:內(nèi)存泄漏,文件描述符泄漏,套接字泄漏,誰知道?

  4. 維護的復(fù)雜性
    維護在處理異常周圍跳躍的代碼更加困難。



查看完整回答
反對 回復(fù) 2019-12-11
  • 3 回答
  • 0 關(guān)注
  • 377 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號