<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>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # Item 26: 只要有可能就推遲變量定義 作者:Scott Meyers 譯者:fatalerror99 (iTePub's Nirvana) 發布:http://blog.csdn.net/fatalerror99/ 只要你定義了一個帶有構造函數和析構函數的類型的變量,當控制流程到達變量定義的時候會使你擔負構造成本,而當變量離開作用域的時候會使你擔負析構成本。如果有無用變量造成這一成本,你就要盡你所能去避免它。 你可能認為你從來不會定義無用的變量,但是也許你應該再想一想。考慮下面這個函數,只要 password 的長度滿足要求,它就返回一個 password 的加密版本。如果 password 太短,函數就會拋出一個定義在標準 C++ 庫中的 logic_error 類型的異常(參見 Item 54): ``` // this function defines the variable "encrypted" too soon std::string encryptPassword(const std::string& password) { using namespace std; string encrypted; if (password.length() < MinimumPasswordLength) { throw logic_error("Password is too short"); } ... // do whatever is necessary to place an // encrypted version of password in encrypted return encrypted; } ``` 對象 encrypted 在這個函數中并不是完全無用,但是如果拋出了一個異常,它就是無用的。換句話說,即使 encryptPassword 拋出一個異常,你也要為構造和析構 encrypted 付出代價。因此得出以下結論:你最好將 encrypted 的定義推遲到你確信你真的需要它的時候: ``` // this function postpones encrypted's definition until it's truly necessary std::string encryptPassword(const std::string& password) { using namespace std; if (password.length() < MinimumPasswordLength) { throw logic_error("Password is too short"); } string encrypted; ... // do whatever is necessary to place an // encrypted version of password in encrypted return encrypted; } ``` 這一代碼仍然沒有達到它本可以達到的那樣緊湊,因為定義 encrypted 的時候沒有任何初始化參數。這就意味著很多情況下將使用它的缺省構造函數,對于一個對象你首先應該做的就是給它一些值,這經常可以通過賦值來完成。Item 4 解釋了為什么缺省構造(default-constructing)一個對象然后賦值給它比用你真正需要它持有的值初始化它更低效。那個分析也適用于此。例如,假設 encryptPassword 的核心部分是在這個函數中完成的: ``` void encrypt(std::string& s); // encrypts s in place ``` 那么,encryptPassword 就可以這樣實現,即使它還不是最好的方法: ``` // this function postpones encrypted's definition until // it's necessary, but it's still needlessly inefficient std::string encryptPassword(const std::string& password) { ... // check length as above string encrypted; // default-construct encrypted encrypted = password; // assign to encrypted encrypt(encrypted); return encrypted; } ``` 一個更可取得方法是用 password 初始化 encrypted,從而跳過毫無意義并可能很昂貴的缺省構造: ``` // finally, the best way to define and initialize encrypted std::string encryptPassword(const std::string& password) { ... // check length string encrypted(password); // define and initialize // via copy constructor encrypt(encrypted); return encrypted; } ``` 這個建議就是本 Item 的標題中的“只要有可能(as long as possible)”的真正含義。你不僅應該推遲一個變量的定義直到你不得不用它之前的最后一刻,而且應該試圖推遲它的定義直到你得到了它的初始化參數。通過這樣的做法,你可以避免構造和析構無用對象,而且還可以避免不必要的缺省構造。更進一步,通過在它們的含義已經非常明確的上下文中初始化它們,有助于對變量的作用文檔化。 “但是對于循環會如何?”你可能會有這樣的疑問。如果一個變量僅僅在一個循環內使用,是循環外面定義它并在每次循環迭代時賦值給它更好一些,還是在循環內部定義這個變量更好一些呢?也就是說,下面這兩個大致的結構中哪個更好一些? ``` // Approach A: define outside loop // Approach B: define inside loop Widget w; for (int i = 0; i < n; ++i){ for (int i = 0; i < n; ++i) { w = some value dependent on i; Widget w(some value dependent on i); ... ... } ``` 這里我將一個類型 string 的對象換成了一個類型 Widget 的對象,以避免對這個對象的構造、析構或賦值操作的成本的任何已有的預見。 對于 Widget 的操作而言,就是下面這兩個方法的成本: * 方法 A:1 個構造函數 + 1 個析構函數 + n 個賦值。 * 方法 B:n 個構造函數 + n 個析構函數。 對于那些賦值的成本低于一個構造函數/析構函數對的成本的類,方法 A 通常更高效。特別是在 n 變得很大的情況下。否則,方法 B 可能更好一些。此外,方法 A 與方法 B 相比,使得名字 w 在一個較大的區域(包含循環的那個區域)內均可見,這可能會破壞程序的易理解性和可維護性。因此得出以下結論:除非你確信以下兩點:(1)賦值比構造函數/析構函數對成本更低,而且(2)你正在涉及你的代碼中的性能敏感的部分,否則,你應該默認使用方法 B。 Things to Remember * 只要有可能就推遲變量定義。這樣可以增加程序的清晰度并提高程序的性能。
                  <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>

                              哎呀哎呀视频在线观看