條款32 盡可能地推遲變數的定義

2022-03-17 19:40:56 字數 1369 閱讀 1745

//

此函式太早定義了變數"encrypted"

string encryptpassword(const

string&password)

進行必要的操作,將口令的加密版本

放進encrypted之中;

return

encrypted;

}

物件encrypted在函式中並非完全沒用,但如果有異常丟擲時,就是無用的。但是,即使encryptpassword丟擲異常(見條款m15),程式也要承擔encrypted構造和析構的開銷。所以,最好將encrypted推遲到確實需要它時才定義:

//

這個函式推遲了encrypted的定義,

//直到真正需要時才定義

string encryptpassword(const

string&password)

string

encrypted;

進行必要的操作,將口令的加密版本

放進encrypted之中;

return

encrypted;

}

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

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

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

//

這個函式推遲了encrypted的定義,

//直到需要時才定義,但還是很低效

string encryptpassword(const

string&password)

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

//

定義和初始化encrypted的最好方式

string encryptpassword(const

string&password)

你不僅要將變數的定義推遲到必須使用它的時候,還要盡量推遲到可以為它提供乙個初始化引數為止。這樣做,不僅可以避免對不必要的物件進行構造和析構,還可以避免無意義的對預設建構函式的呼叫。而且,在對變數進行初始化的場合下,變數本身的用途不言自明,所以在這裡定義變數有益於表明變數的含義。

盡可能地推遲變數的定義

是的,我們同意c語言中變數要放在模組頭部定義的規定 但在c 中,還是取消這種做法吧,它沒必要,不自然,而且昂貴。還記得嗎?如果定義了乙個有建構函式和析構函式的型別的變數,當程式執行到變數定義之處時,必然面臨構造的開銷 當變數離開它的生命空間時,又要承擔析構的開銷。這意味著定義無用的變數必然伴隨著不必...

C 程式設計實用技巧 32 盡可能地推遲變數的定義

是的,我們同意c語言中變數要放在模組頭部定義的規定 但在c 中,還是取消這種做法吧,它沒必要,不自然,而且昂貴。還記得嗎?如果定義了乙個有建構函式和析構函式的型別的變數,當程式執行到變數定義之處時,必然面臨構造的開銷 當變數離開它的生命空間時,又要承擔析構的開銷。這意味著定義無用的變數必然伴隨著不必...

條款26 盡可能延後變數定義的出現時間

考慮如下 std string encryptpasswd const std string passwd return encryted 上述函式中的encrypted物件未完全使用,當encryptpasswd丟出異常時,仍需要付出encrypted的構造和析構成本,所以最好延後encrypte...