盡可能地推遲變數的定義

2021-04-12 18:28:54 字數 1753 閱讀 7130

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

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

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

// 此函式太早定義了變數"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語言中的做法嗎?每個變數的定義旁最好要有一條短注釋,以標明這個變數將來做什麼用。而現在,乙個合適的名字(見條款28),再結合有意義的初始化引數,你就可以實現每個程式設計師的夢想:通過可靠的變數本身來消除對它不必要的注釋。

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

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

此函式太早定義了變數 encrypted string encryptpassword const string password 進行必要的操作,將口令的加密版本 放進encrypted之中 return encrypted 物件encrypted在函式中並非完全沒用,但如果有異常丟擲時,就是無用...

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

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

C 盡可能延後變數定義式的出現時間

20180315 c 盡可能延後變數定義式的出現時間 只要定義了變數,其型別就帶有乙個建構函式 乙個析構函式。當程式的控制流到達這個變數定義式時,就得承受構造成本,當變數離開其作用域時,就得承受析構成本。即使這個變數沒被使用,仍需耗費這些成本,所以要避免這種情形。eg 計算密碼的加密版本後退出的程式...