<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          C++核心準(zhǔn)則E.6:使用RAII防止資源泄露

          E.6: Use RAII to prevent leaks

          E.6:使用RAII防止資源泄露


          Reason(原因)

          Leaks are typically unacceptable. Manual resource release is error-prone. RAII ("Resource Acquisition Is Initialization") is the simplest, most systematic way of preventing leaks.

          資源泄露通常都是不可接受的。手動(dòng)釋放資源容易引發(fā)錯(cuò)誤。RAII(“資源請(qǐng)求即初始化”)是防止泄露最簡(jiǎn)單,更加系統(tǒng)化的方式。


          Example(示例)

          void f1(int i)   // Bad: possible leak
          {
          int* p = new int[12];
          // ...
          if (i < 17) throw Bad{"in f()", i};
          // ...
          }

          We could carefully release the resource before the throw:

          在拋出異常之前,我們必須小心地釋放資源:

          void f2(int i)   // Clumsy and error-prone: explicit release
          {
          int* p = new int[12];
          // ...
          if (i < 17) {
          delete[] p;
          throw Bad{"in f()", i};
          }
          // ...
          }

          This is verbose. In larger code with multiple possible?throws explicit releases become repetitive and error-prone.

          代碼冗長(zhǎng)。在更大規(guī)模的,存在更多的拋出異常的可能性的代碼中,顯示釋放資源會(huì)更加繁復(fù)和易錯(cuò)。

          void f3(int i)   // OK: resource management done by a handle (but see below)
          {
          auto p = make_unique(12);
          // ...
          if (i < 17) throw Bad{"in f()", i};
          // ...
          }

          Note that this works even when the?throw?is implicit because it happened in a called function:

          需要注意的是,即使是隱式的拋出動(dòng)作(因?yàn)樗谡{(diào)用的函數(shù)中發(fā)生),這段代碼仍然可以起作用。

          void f4(int i)   // OK: resource management done by a handle (but see below)
          {
          auto p = make_unique(12);
          // ...
          helper(i); // may throw
          // ...
          }

          Unless you really need pointer semantics, use a local resource object:

          除非你真的需要指針語(yǔ)義,否則使用一個(gè)局部的資源對(duì)象:

          void f5(int i)   // OK: resource management done by local object
          {
          vector v(12);
          // ...
          helper(i); // may throw
          // ...
          }

          That's even simpler and safer, and often more efficient.

          這樣更簡(jiǎn)單,更安全,甚至更高效。


          Note(注意)

          If there is no obvious resource handle and for some reason defining a proper RAII object/handle is infeasible, as a last resort, cleanup actions can be represented by a?final_action?object.

          如果沒(méi)有明顯的資源句柄而且由于某種原因定義適當(dāng)?shù)腞AII對(duì)象/句柄不可行,作為最有手段,可以通過(guò)一個(gè)final_actrion對(duì)象實(shí)現(xiàn)清理動(dòng)作。


          Note(注意)

          But what do we do if we are writing a program where exceptions cannot be used? First challenge that assumption; there are many anti-exceptions myths around. We know of only a few good reasons:

          但是,如果我們?cè)趯?xiě)一個(gè)程序而無(wú)法使用異常處理時(shí),我們應(yīng)該做什么?首先挑戰(zhàn)這個(gè)假設(shè);存在很多反對(duì)使用異常的神話。我們只知道很少幾個(gè)是正當(dāng)理由:

          • We are on a system so small that the exception support would eat up most of our 2K memory.

          • 你正在工作的系統(tǒng)是如此之小,支持異常會(huì)吃掉最多2K內(nèi)存(都無(wú)法承受)。

          • We are in a hard-real-time system and we don't have tools that guarantee us that an exception is handled within the required time.

          • 我們處在一個(gè)硬實(shí)時(shí)系統(tǒng)中,沒(méi)有工具可以保證異常處理會(huì)在要求的時(shí)間內(nèi)完成。

          • We are in a system with tons of legacy code using lots of pointers in difficult-to-understand ways (in particular without a recognizable ownership strategy) so that exceptions could cause leaks.

          • 我們所處的系統(tǒng)包含成噸的遺留代碼,這些代碼以難以理解的方式大量使用指針(通常沒(méi)有可識(shí)別的所有權(quán)策略),因此異??赡芤l(fā)泄露。

          • Our implementation of the C++ exception mechanisms is unreasonably poor (slow, memory consuming, failing to work correctly for dynamically linked libraries, etc.). Complain to your implementation purveyor; if no user complains, no improvement will happen.

          • 正在使用的C++實(shí)現(xiàn),其異常機(jī)制超乎想象的差勁(緩慢,過(guò)多消費(fèi)內(nèi)存,使用動(dòng)態(tài)鏈接庫(kù)時(shí)無(wú)法工作等)。投訴你的提供者;如果沒(méi)有用戶(hù)投訴,就不會(huì)發(fā)生改進(jìn)。

          • We get fired if we challenge our manager's ancient wisdom.

          • 如果我們挑戰(zhàn)管理者的老套經(jīng)驗(yàn),就會(huì)被開(kāi)除。

          Only the first of these reasons is fundamental, so whenever possible, use exceptions to implement RAII, or design your RAII objects to never fail. When exceptions cannot be used, simulate RAII. That is, systematically check that objects are valid after construction and still release all resources in the destructor. One strategy is to add a?valid()?operation to every resource handle:

          這些原因中只有第一個(gè)是根本性的,因此只要可能就使用異常來(lái)實(shí)現(xiàn)RAII,或者設(shè)計(jì)自己的RAII對(duì)象來(lái)保證永遠(yuǎn)不失敗。如果無(wú)法使用異常,就模仿RAII的動(dòng)作。即系統(tǒng)化的檢查對(duì)象被構(gòu)建之后的有效性和析構(gòu)時(shí)會(huì)釋放所有資源。一個(gè)策略是為每一個(gè)資源句柄增加一個(gè)valid操作。

          void f()
          {
          vector vs(100); // not std::vector: valid() added
          if (!vs.valid()) {
          // handle error or exit
          }

          ifstream fs("foo"); // not std::ifstream: valid() added
          if (!fs.valid()) {
          // handle error or exit
          }

          // ...
          } // destructors clean up as usual

          Obviously, this increases the size of the code, doesn't allow for implicit propagation of "exceptions" (valid()?checks), and?valid()?checks can be forgotten. Prefer to use exceptions.

          很顯然,這回增加代碼的大小,不允異常的隱式傳播(通過(guò)有效性檢查),而且有效性檢查可以被忘記。最好使用異常。

          See also:?Use of?noexcept

          參見(jiàn):使用noexcept。


          Enforcement(實(shí)時(shí)建議)

          ???


          原文鏈接https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#e6-use-raii-to-prevent-leaks

          新書(shū)介紹

          以下是本人3月份出版的新書(shū),拜托多多關(guān)注!


          本書(shū)利用Python 的標(biāo)準(zhǔn)GUI 工具包tkinter,通過(guò)可執(zhí)行的示例對(duì)23 個(gè)設(shè)計(jì)模式逐個(gè)進(jìn)行說(shuō)明。這樣一方面可以使讀者了解真實(shí)的軟件開(kāi)發(fā)工作中每個(gè)設(shè)計(jì)模式的運(yùn)用場(chǎng)景和想要解決的問(wèn)題;另一方面通過(guò)對(duì)這些問(wèn)題的解決過(guò)程進(jìn)行說(shuō)明,讓讀者明白在編寫(xiě)代碼時(shí)如何判斷使用設(shè)計(jì)模式的利弊,并合理運(yùn)用設(shè)計(jì)模式。

          對(duì)設(shè)計(jì)模式感興趣而且希望隨學(xué)隨用的讀者通過(guò)本書(shū)可以快速跨越從理解到運(yùn)用的門(mén)檻;希望學(xué)習(xí)Python GUI 編程的讀者可以將本書(shū)中的示例作為設(shè)計(jì)和開(kāi)發(fā)的參考;使用Python 語(yǔ)言進(jìn)行圖像分析、數(shù)據(jù)處理工作的讀者可以直接以本書(shū)中的示例為基礎(chǔ),迅速構(gòu)建自己的系統(tǒng)架構(gòu)。




          覺(jué)得本文有幫助?請(qǐng)分享給更多人。

          關(guān)注微信公眾號(hào)【面向?qū)ο笏伎肌枯p松學(xué)習(xí)每一天!

          面向?qū)ο箝_(kāi)發(fā),面向?qū)ο笏伎迹?/span>


          瀏覽 64
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  大香蕉伊人电影 | 99色视频| 香蕉视频三区 | 外国女人操逼视频网址 | 嫩逼网站|