<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # Item 17: 在一個獨立的語句中將 new 出來的對象存入智能指針 作者:Scott Meyers 譯者:fatalerror99 (iTePub's Nirvana) 發布:http://blog.csdn.net/fatalerror99/ 假設我們有一個函數取得我們的處理優先級,而第二個函數根據優先級針對動態分配的 Widget 做一些處理: ``` int priority(); void processWidget(std::tr1::shared_ptr&lt;Widget&gt; pw, int priority); ``` 不要忘記使用對象管理資源的至理名言(參見 Item 13),processWidget 為處理動態分配的 Widget 使用了一個智能指針(在此,是一個 tr1::shared_ptr)。 現在考慮一個對 processWidget 的調用: ``` processWidget(new Widget, priority()); ``` 且慢,別想這樣調用。它不能編譯。tr1::shared_ptr 的構造函數取得一個裸指針(raw pointer)應該是顯式的,所以不能從一個由 "new Widget" 返回的裸指針隱式轉型到 processWidget 所需要的 tr1::shared_ptr。下面的代碼,無論如何,是可以編譯的: ``` processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority()); ``` 令人驚訝的是,盡管我們在這里各處都使用了對象管理資源,這個調用還是可能泄漏資源。下面就來說明這是如何發生的。 在編譯器能生成一個對 processWidget 的調用之前,它們必須傳遞實際參數來計算形式參數的值。第二個實際參數不過是對函數 priority 的調用,但是第一個實際參數("std::tr1::shared_ptr&lt;Widget&gt;(new Widget)"),由兩部分組成 * 表達式 "new Widget" 的執行。 * 一個對 tr1::shared_ptr 的構造函數的調用。 在 processWidget 能被調用之前,編譯器必須為這三件事情生成代碼: * 調用 priority。 * 執行 "new Widget"。 * 調用 tr1::shared_ptr 的構造函數。 C++ 編譯器允許在一個相當大的范圍內決定這三件事被完成的順序。(這里與 Java 和 C# 等語言的處理方式不同,那些語言里函數參數總是按照一個精確的順序被計算。)"new Widget" 表達式一定在 tr1::shared_ptr 的構造函數能被調用之前執行,因為這個表達式的結果要作為一個參數傳遞給 tr1::shared_ptr 的構造函數,但是 priority 的調用可以被第一個,第二個或第三個執行。如果編譯器選擇第二個執行它(大概這樣能使它們生成更有效率的代碼),我們最終得到這樣一個操作順序: 1\. 執行 "new Widget"。 2\. 調用 priority。 3\. 調用 tr1::shared_ptr 的構造函數。 但是請考慮,如果對 priority 的調用引發一個異常將發生什么。在這種情況下,從 "new Widget" 返回的指針被丟失,因為它沒有被存入我們期望能阻止資源泄漏的 tr1::shared_ptr。由于一個異常可能插入資源創建的時間和將資源交給一個資源管理對象的時間之間,所以調用 processWidget 可能會發生一次泄漏。 避免類似問題的方法很簡單:用一個單獨的語句創建 Widget 并將它存入一個智能指針,然后將這個智能指針傳遞給 processWidget: ``` std::tr1::shared_ptr<Widget> pw(new Widget); // store newed object // in a smart pointer in a // standalone statement processWidget(pw, priority()); // this call won't leak ``` 這樣做是因為編譯器在不同的語句之間重新安排操作順序的活動余地比在一個語句之內要小得多。"new Widget" 表達式和 tr1::shared_ptr 的構造函數的調用與 priority 的調用在不同的語句中,所以編譯器不會允許 priority 的調用插入它們中間。 Things to Remember * 在一個獨立的語句中將 new 出來的對象存入智能指針。如果疏忽了這一點,當異常發生時,可能引起微妙的資源泄漏。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看