亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

成員初始化列表與構造函數體中的區別詳細解析

2020-01-26 15:47:45
字體:
來源:轉載
供稿:網友

論壇中回答一個別人問題

C++ Primer中在講構造函數初始化列表的時候有這么一段話:
無論是在構造函數初始化列表中初始化成員,還是在構造函數體中對它們賦值,最終結果是相同的。不同之處在于,使用構造函數初始化列表的版本初始化數據成員,沒有定義初始化列表的構造函數版本在構造函數體中對數據成員賦值。

請問這里的初始化數據成員與對數據成員賦值的含義是什么?有什么區別?

我知道在數據成員有默認構造函數時是有不同的,但對其他類型的成員呢?其他類型成員的初始化和賦值有區別嗎?
=========================================================================
是這個意思:
首先把數據成員按類型分類
1。內置數據類型,復合類型(指針,引用)
2。用戶定義類型(類類型)

分情況說明:
對于類型1,在成員初始化列表和構造函數體內進行,在性能和結果上都是一樣的
對于類型2,結果上相同,但是性能上存在很大的差別

因為類類型的數據成員對象在進入函數體是已經構造完成,也就是說在成員初始化列表處進行構造對象的工作,這是調用一個構造函數,在進入函數體之后,進行的是 對已經構造好的類對象的賦值,又調用個拷貝賦值操作符才能完成(如果并未提供,則使用編譯器提供的默認按成員賦值行為)

舉個例說明
class A;
class B
{public:
B(){a = 3;}
private:
A a;
}

class A
{public:
A(){}
A(int){value = 3;}
int value;
}

像上面,我們使a對象的value為3,調用一個A的構造函數+一個默認拷貝賦值符,才達到目的
B::B():a(3){}
像這樣,只調用了一個構造函數就達到了所需的對象啦,所以性能好的

轉載他人一篇

我的問題是關于初始化C++類成員的。我見過許多這樣的代碼(包括在你的欄目中也見到過):

復制代碼 代碼如下:

CSomeClass::CSomeClass()

{

    x=0;

    y=1;

}


而在別的什么地方則寫成下面的樣子:
復制代碼 代碼如下:

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

{

}


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

回答

從技術上說,你的程序員朋友是對的,但是在大多數情況下,兩者實際上沒有區別。有兩個原因使得我們選擇第二種語法,它被稱為成員初始化列表:一個原因是必須的,另一個只是出于效率考慮。

讓我們先看一下第一個原因――必要性。設想你有一個類成員,它本身是一個類或者結構,而且只有一個帶一個參數的構造函數。

復制代碼 代碼如下:

class CMember {

public:

    CMember(int x) { ... }

};


因為Cmember有一個顯式聲明的構造函數,編譯器不產生一個缺省構造函數(不帶參數),所以沒有一個整數就無法創建Cmember的一個實例。

CMember* pm = new CMember;        // Error!!
CMember* pm = new CMember(2);     // OK

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

復制代碼 代碼如下:

class CMyClass {

    CMember m_member;

public:

    CMyClass();

};

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

CMyClass::CMyClass() : m_member(2)

{

•••

}


沒有其它辦法將參數傳遞給m_member,如果成員是一個常量對象或者引用也是一樣。根據C++的規則,常量對象和引用不能被賦值,它們只能被初始化。

第二個原因是出于效率考慮,當成員類具有一個缺省的構造函數和一個賦值操作符時。MFC的Cstring提供了一個完美的例子。假定你有一個類CmyClass具有一個Cstring類型的成員m_str,你想把它初始化為"yada yada."。你有兩種選擇:

復制代碼 代碼如下:

CMyClass::CMyClass() {

    // 使用賦值操作符

    // CString::operator=(LPCTSTR);

    m_str = _T("yada yada");

}

//使用類成員列表

// 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(int x, int y);

    int m_x;

    int m_y;

};

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會更加自然的出現。有兩種方法避免它,一個是總是按照你希望它們 被初始化的順序聲明成員,第二個是,如果你決定使用初始化列表,總是按照它們聲明的順序羅列這些成員。這將有助于消除混淆。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩动漫免费观看电视剧高清| 黄网动漫久久久| 欧日韩在线观看| 国产精品天天狠天天看| 亚洲成av人乱码色午夜| 成人激情春色网| 国产日本欧美一区| 欧美专区福利在线| 91精品视频播放| 亚洲图片欧美日产| 亚洲国产天堂网精品网站| 亚洲二区在线播放视频| 一区二区三区美女xx视频| 日韩在线视频网| 国产精品69久久| 国产精品7m视频| 亚洲女人被黑人巨大进入al| 亚洲在线一区二区| 91香蕉国产在线观看| 久久久黄色av| 国产成人精品免费视频| 亚洲va久久久噜噜噜久久天堂| 亚洲一区二区三区视频播放| 国内成人精品视频| 久久精品国产精品亚洲| 国产精品aaaa| 亚洲xxxx在线| 亚洲视频欧洲视频| 91国语精品自产拍在线观看性色| 亚洲一区中文字幕在线观看| 欧美日韩国产成人在线| 中文一区二区视频| 黄色91在线观看| 91午夜理伦私人影院| 91亚洲国产成人久久精品网站| 亚洲日韩中文字幕| 伊人久久大香线蕉av一区二区| 国产福利精品视频| 亚洲国产美女精品久久久久∴| 欧美黄色免费网站| 亚洲免费电影在线观看| 成人av番号网| 亚洲成色777777女色窝| 日本精品在线视频| 91极品女神在线| 久久久99久久精品女同性| 国产精品成久久久久三级| www日韩中文字幕在线看| 91av免费观看91av精品在线| 国产精品成人v| 亚洲第一精品福利| 欧美国产日韩视频| 亚洲国产精品专区久久| 亚洲护士老师的毛茸茸最新章节| 日韩欧美在线视频观看| 国产精品综合不卡av| 亚洲图片在线综合| 亚洲伊人久久综合| 国产精品视频xxx| 欧美性猛交99久久久久99按摩| 日日狠狠久久偷偷四色综合免费| 久久久久亚洲精品国产| 国产视频久久久| 精品亚洲va在线va天堂资源站| 欧美激情一区二区三区成人| 国产亚洲视频在线| 日韩美女在线看| 波霸ol色综合久久| 亚洲天堂av在线免费观看| 亚洲国产成人av在线| 精品国产一区二区三区久久狼5月| 136fldh精品导航福利| 亚洲大尺度美女在线| 国产xxx69麻豆国语对白| 久久亚洲春色中文字幕| 国产成人av在线播放| 欧美日韩国产综合新一区| 亚洲免费高清视频| 日韩精品视频在线观看免费| 欧美精品电影免费在线观看| 亚洲成在人线av| 综合国产在线视频| 日韩国产在线看| 成人黄色在线免费| 黑人巨大精品欧美一区二区| 国内外成人免费激情在线视频网站| 欧美激情乱人伦| 国产在线高清精品| 中文字幕九色91在线| 日韩美女在线观看一区| 久久精品亚洲精品| 欧美乱妇40p| 亚洲字幕一区二区| 日本欧美精品在线| 亚洲第一精品久久忘忧草社区| 精品一区二区三区电影| 久久香蕉国产线看观看网| 国产精品专区一| 亚洲综合视频1区| 中文字幕亚洲一区在线观看| 中文字幕日韩电影| 欧美日韩精品中文字幕| 亚洲国产一区二区三区在线观看| 日韩欧美国产激情| 一区二区三区四区视频| 日韩av在线不卡| 久久视频国产精品免费视频在线| 欧美精品免费在线| 久久亚洲精品中文字幕冲田杏梨| 欧美在线一级va免费观看| 国产精品av免费在线观看| 久久视频在线看| 高清欧美性猛交| 欧美激情图片区| 岛国视频午夜一区免费在线观看| 日本高清不卡在线| 欧美国产精品人人做人人爱| 国产免费一区二区三区香蕉精| 国内精品小视频在线观看| 国产国语videosex另类| 亚洲的天堂在线中文字幕| 精品一区电影国产| 国产精品美乳在线观看| 亚洲免费人成在线视频观看| 久久久在线视频| 亚洲xxxx3d| 高清一区二区三区四区五区| 91在线中文字幕| 一区二区国产精品视频| 久久成人免费视频| 日本精品一区二区三区在线播放视频| 欧美精品一区二区三区国产精品| 91精品国产91久久久久久不卡| 亚洲a成v人在线观看| 成人www视频在线观看| 亚洲va国产va天堂va久久| 91亚洲精品一区二区| 亚洲第一国产精品| 亚洲人成欧美中文字幕| 91成品人片a无限观看| 亚洲免费人成在线视频观看| 97国产成人精品视频| 日韩在线一区二区三区免费视频| 成人淫片在线看| 久久久久免费精品国产| 国产精品成人aaaaa网站| 久久久久久久久久久久久久久久久久av| 91亚洲精品久久久| 日韩人在线观看| 91精品国产色综合| 国产专区欧美专区| 欧美成人久久久| 尤物精品国产第一福利三区| 亚洲欧美制服中文字幕| 精品国产一区二区三区久久久狼| 国产亚洲精品美女久久久久| 国产精品久久久久av| 亚洲精品在线视频| 欧美精品videofree1080p| 国产日韩精品入口| 美女福利视频一区| 黄色成人在线播放| 欧美精品免费在线观看| 91产国在线观看动作片喷水|