在網上摘到的好內容,以備檢視

2021-05-08 03:15:39 字數 2824 閱讀 5984

1. c++中:符號的意思

我的問題是關於初始化

c++類成員的。我見過許多這樣的**(包括在你的欄目中也見到過):

csomeclass::csomeclass()  

而在別的什麼地方則寫成下面的樣子:

csomeclass::csomeclass()   :   x(0),   y(1)  

我的一些程式設計師朋友說第二種方法比較好,但他們都不知道為什麼是這樣。你能告訴我這兩種類成員初始化方法的區別嗎?

回答從技術上說,你的程式設計師朋友是對的,但是在大多數情況下,兩者實際上沒有區別。有兩個原因使得我們選擇第二種語法,

它被稱為成員初始化列表:乙個原因是必須的,另乙個只是出於效率考慮。

讓我們先看一下第乙個原因

——必要性。設想你有乙個類成員,它本身是乙個類或者結構,而且只有乙個帶乙個引數的建構函式。

class   cmember    

};  

因為cmember

有乙個顯式宣告的建構函式,編譯器不產生乙個預設建構函式(不帶引數),所以沒有乙個整數就無法建立

cmember

的乙個例項。

cmember*   pm   =   new   cmember;                 //   error!!  

cmember*   pm   =   new   cmember(2);           //   ok  

如果cmember

是另乙個類的成員,你怎樣初始化它呢?你必須使用成員初始化列表。

class   cmyclass   ;  

//必須使用成員初始化列表

cmyclass::cmyclass()   :   m_member(2)  

沒有其它辦法將引數傳遞給

m_member

,如果成員是乙個常量物件或者引用也是一樣。根據

c++的規則,常量物件和引用不能被賦值,它們只能被初始化。

第二個原因是出於效率考慮,當成員類具有乙個預設的建構函式和乙個賦值操作符時。

mfc的

cstring

提供了乙個完美的例子。

假定你有乙個類

cmyclass

具有乙個

cstring

型別的成員

m_str

,你想把它初始化為

"yada   yada."

。你有兩種選擇:

cmyclass::cmyclass()    

//使用類成員列表

//   and   constructor   cstring::cstring(lpctstr)  

cmyclass::cmyclass()   :   m_str(_t("yada   yada"))  

在它們之間有什麼不同嗎?是的。編譯器總是確保所有成員物件在建構函式體執行之前初始化,因此在第乙個例子中編譯

的**將呼叫

cstring::cstring

來初始化

m_str

,這在控制到達賦值語句前完成。在第二個例子中編譯器產生乙個對

cstring::   cstring(lpctstr)

的呼叫並將

"yada   yada"

傳遞給這個函式。結果是在第乙個例子中呼叫了兩個

cstring

函式(建構函式和賦值操作符),而在第二個例子中只呼叫了乙個函式。在

cstring

的例子裡這是無所謂的,因為預設建構函式是

內聯的,

cstring

只是在需要時為字串分配記憶體(即,當你實際賦值時)。但是,一般而言,重複的函式呼叫是浪費資源的,

尤其是當建構函式和賦值操作符分配記憶體的時候。在一些大的類裡面,你可能擁有乙個建構函式和乙個賦值操作符都要呼叫同

乙個負責分配大量記憶體空間的

init

函式。在這種情況下,你必須使用初始化列表,以避免不要的分配兩次記憶體。在內部型別如

ints

或者longs

或者其它沒有建構函式的型別下,在初始化列表和在建構函式體內賦值這兩種方法沒有效能上的差別。不管用那

一種方法,都只會有一次賦值發生。有些程式設計師說你應該總是用初始化列表以保持良好習慣,但我從沒有發現根據需要在這兩種

方法之間轉換有什麼困難。在程式設計風格上,我傾向於在主體中使用賦值,因為有更多的空間用來格式化和新增注釋,你可以寫出

這樣的語句:

x=y=z=0;

或者memset(this,0,sizeof(this));  

注意第二個片斷絕對是非物件導向的。

當我考慮初始化列表的問題時,有乙個奇怪的特性我應該警告你,它是關於

c++初始化類成員的,它們是按照宣告的順序初

始化的,而不是按照出現在初始化列表中的順序。

class   cmyclass   ;  

cmyclass::cmyclass(int   i)   :   m_y(i),   m_x(m_y)  

你可能以為上面的**將會首先做

m_y=i

,然後做

m_x=m_y

,最後它們有相同的值。但是編譯器先初始化

m_x,然後是

m_y,

,因為它們是按這樣的順序宣告的。結果是

m_x將有乙個不可**的值。我的例子設計來說明這一點,然而這種

bug會更加自然的出現。

有兩種方法避免它,乙個是總是按照你希望它們被初始化的順序宣告成員,第二個是,如果你決定使用初始化列表,總是按照

它們宣告的順序羅列這些成員。這將有助於消除混淆。

在網上搜到的題目

文章出自網魂工作室 附錄c c c試題的答案與評分標準 一 請填寫bool float,指標變數 與 零值 比較的 if 語句。10分 請寫出 bool flag 與 零值 比較的 if 語句。3分 標準答案 if flag if flag 如下寫法均屬不良風格,不得分。if flag true i...

在網上找的VARIANT的用法,私藏了

variant的結構可以參考標頭檔案vc98 include oaidl.h中關於結構體tagvariant的定義。struct tagvariant variant name 4 variant name 3 variant name 2 decimal decval variant name 1...

麻省的表哥,教你如何利用python在網上秒接單

前言 學習程式設計不僅僅可以讓你找到乙份高薪的工作,而且如果你並不打算轉行或者還在校學生的話,你可以考慮在網上接一些python相關的小單子,不僅可以給自己練手,還能賺錢。而且很多接單網上面的案例都比較簡單,可能只需要你十幾分鐘就能搞定的小案例,都可以獲得幾百元的金額。如下圖 當然也幾千或者上萬的單...