儘可能地延遲變數的定義

來源:互聯網
上載者:User

是的,我們同意C語言中變數要放在模組頭部定義的規定;但在C++中,還是取消這種做法吧,它沒必要,不自然,而且昂貴。

還記得嗎?如果定義了一個有建構函式和解構函式的類型的變數,當程式運行到變數定義之處時,必然面臨構造的開銷;當變數離開它的生命空間時,又要承擔析構的開銷。這意味著定義無用的變數必然伴隨著不必要的開銷,所以只要可能,就要避免這種情況發生。

正如我所知道的,你的編程方式優雅而不失老練。所以你可能會在想,你決不會定義一個無用的變數,所以本條款的建議不適用於你嚴謹緊湊的編程風格。但別急,看看下面這個函數:當口令夠長時,它返回口令的加密版本;當口令太短時,函數拋出logic_error類型的異常(logic_error類型在C++標準庫中定義,參見條款49):

// 此函數太早定義了變數"encrypted"
string encryptPassword(const string& password)
{
  string encrypted;

  if (password.length() < MINIMUM_PASSWORD_LENGTH) {
     throw logic_error("Password is too short");
  }

  進行必要的操作,將口令的加密版本 
  放進encrypted之中;

  return encrypted;
}

對象encrypted在函數中並非完全沒用,但如果有異常拋出時,就是無用的。但是,即使encryptPassword拋出異常(見條款M15),程式也要承擔encrypted構造和析構的開銷。所以,最好將encrypted延遲到確實需要它時才定義:

// 這個函數延遲了encrypted的定義,
// 直到真正需要時才定義
string encryptPassword(const string& password)
{
  if (password.length() < MINIMUM_PASSWORD_LENGTH) {
    throw logic_error("Password is too short");
  }

  string encrypted;

  進行必要的操作,將口令的加密版本 
  放進encrypted之中;

  return encrypted;
}

這段代碼還不是那麼嚴謹,因為encrypted定義時沒有帶任何初始化參數。這將導致它的預設建構函式被調用。大多數情況下,對一個對象首先做的一件事是給它一個什麼值,這通常用賦值來實現。條款12說明了為什麼"預設構造一個對象然後對它賦值"比"用真正想要的值來初始化這個對象"效率要低得多。這一論斷在此一樣適用。例如,假設encryptPassword中最難處理的部分在這個函數中進行:

void encrypt(string& s);      // s在此加密

於是encryptPassword可以象這樣實現(當然,它不是最好的實現方式):

// 這個函數延遲了encrypted的定義,
// 直到需要時才定義,但還是很低效
string encryptPassword(const string& password)
{
  ...                      // 同上,檢查長度

  string encrypted;        // 預設構造encrypted
  encrypted = password;    // 給encrypted賦值
  encrypt(encrypted);
  return encrypted;
}

更好的方法是用password來初始化encrypted,從而繞過了對預設建構函式不必要的調用:

// 定義和初始化encrypted的最好方式
string encryptPassword(const string& password)
{
  ...                             // 檢查長度

  string encrypted(password);     // 通過拷貝建構函式定義並初始化

  encrypt(encrypted);
  return encrypted;
}

這段代碼闡述了本條款的標題中"儘可能"這三個字的真正含義。你不僅要將變數的定義延遲到必須使用它的時候,還要盡量延遲到可以為它提供一個初始化參數為止。這樣做,不僅可以避免對不必要的對象進行構造和析構,還可以避免無意義的對預設建構函式的調用。而且,在對變數進行初始化的場合下,變數本身的用途不言自明,所以在這裡定義變數有益於表明變數的含義。還記得在C語言中的做法嗎?每個變數的定義旁最好要有一條短注釋,以標明這個變數將來做什麼用。而現在,一個合適的名字(見條款28),再結合有意義的初始化參數,你就可以實現每個程式員的夢想:通過可靠的變數本身來消除對它不必要的注釋。

延遲變數定義可以提高程式的效率,增強程式的條理性,還可以減少對變數含義的注釋。看來是該和那些開放式模組的變數定義吻別了。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.