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

2021-06-16 16:20:50 字數 1884 閱讀 4381

是的,我們同意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),再結合有意義的初始化引數,你就可以實現每個程式設計師的夢想:通過可靠的變數本身來消除對它不必要的注釋。

推遲變數定義可以提高程式的效率,增強程式的條理性,還可以減少對變數含義的注釋。

linux 程式設計實用技巧

1 sizeof 引數為指標的問題。int i int j 10 sizeof i sizeof引數為指標時,返回指標資料型別所佔空間,一般為4 unsigned int 所佔byte sizeof j sizeof引數為陣列時,返回陣列所佔空間,此時為4 10 40 2 多執行緒中需考慮重入的問題...

C 實用技巧(二)

上一篇文章講到了如何檢查記憶體洩露。其實只要肯用c 的stl裡面的高階功能的話,記憶體洩露是很容易避免的。我在開發vczh library 3.0的時候,所有的測試用例都保證跑完了沒有記憶體洩露。但是很可惜有些c 團隊不能使用異常,更甚者不允許寫建構函式析構函式之類,前乙個還好,後乙個簡直就是在用c...

C 程式設計實用技巧 專家講述C 程式設計的竅門

從c轉向c 對每個人來說,習慣c 需要一些時間,對於已經熟悉c的程式設計師來說,這個過程尤其令人苦惱。因為c是c 的子集,所有的c的技術都可以繼續使用,但很多用起來又不太合適。例如,c 程式設計師會認為指標的指標看起來很古怪,他們會問 為什麼不用指標的引用來代替呢?c是一種簡單的語言。它真正提供的只...