欧美大屁股bbbbxxxx,狼人大香伊蕉国产www亚洲,男ji大巴进入女人的视频小说,男人把ji大巴放进女人免费视频,免费情侣作爱视频

歡迎來(lái)到入門(mén)教程網(wǎng)!

C語(yǔ)言

當(dāng)前位置:主頁(yè) > 軟件編程 > C語(yǔ)言 >

成員初始化列表與構(gòu)造函數(shù)體中的區(qū)別詳細(xì)解析

來(lái)源:本站原創(chuàng)|時(shí)間:2020-01-10|欄目:C語(yǔ)言|點(diǎn)擊: 次

論壇中回答一個(gè)別人問(wèn)題

C++ Primer中在講構(gòu)造函數(shù)初始化列表的時(shí)候有這么一段話:
無(wú)論是在構(gòu)造函數(shù)初始化列表中初始化成員,還是在構(gòu)造函數(shù)體中對(duì)它們賦值,最終結(jié)果是相同的。不同之處在于,使用構(gòu)造函數(shù)初始化列表的版本初始化數(shù)據(jù)成員,沒(méi)有定義初始化列表的構(gòu)造函數(shù)版本在構(gòu)造函數(shù)體中對(duì)數(shù)據(jù)成員賦值。

請(qǐng)問(wèn)這里的初始化數(shù)據(jù)成員與對(duì)數(shù)據(jù)成員賦值的含義是什么?有什么區(qū)別?

我知道在數(shù)據(jù)成員有默認(rèn)構(gòu)造函數(shù)時(shí)是有不同的,但對(duì)其他類(lèi)型的成員呢?其他類(lèi)型成員的初始化和賦值有區(qū)別嗎?
=========================================================================
是這個(gè)意思:
首先把數(shù)據(jù)成員按類(lèi)型分類(lèi)
1。內(nèi)置數(shù)據(jù)類(lèi)型,復(fù)合類(lèi)型(指針,引用)
2。用戶定義類(lèi)型(類(lèi)類(lèi)型)

分情況說(shuō)明:
對(duì)于類(lèi)型1,在成員初始化列表和構(gòu)造函數(shù)體內(nèi)進(jìn)行,在性能和結(jié)果上都是一樣的
對(duì)于類(lèi)型2,結(jié)果上相同,但是性能上存在很大的差別

因?yàn)轭?lèi)類(lèi)型的數(shù)據(jù)成員對(duì)象在進(jìn)入函數(shù)體是已經(jīng)構(gòu)造完成,也就是說(shuō)在成員初始化列表處進(jìn)行構(gòu)造對(duì)象的工作,這是調(diào)用一個(gè)構(gòu)造函數(shù),在進(jìn)入函數(shù)體之后,進(jìn)行的是 對(duì)已經(jīng)構(gòu)造好的類(lèi)對(duì)象的賦值,又調(diào)用個(gè)拷貝賦值操作符才能完成(如果并未提供,則使用編譯器提供的默認(rèn)按成員賦值行為)

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

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

像上面,我們使a對(duì)象的value為3,調(diào)用一個(gè)A的構(gòu)造函數(shù)+一個(gè)默認(rèn)拷貝賦值符,才達(dá)到目的
B::B():a(3){}
像這樣,只調(diào)用了一個(gè)構(gòu)造函數(shù)就達(dá)到了所需的對(duì)象啦,所以性能好的

轉(zhuǎn)載他人一篇

我的問(wèn)題是關(guān)于初始化C++類(lèi)成員的。我見(jiàn)過(guò)許多這樣的代碼(包括在你的欄目中也見(jiàn)到過(guò)):

復(fù)制代碼 代碼如下:

CSomeClass::CSomeClass()

{

    x=0;

    y=1;

}


而在別的什么地方則寫(xiě)成下面的樣子:
復(fù)制代碼 代碼如下:

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

{

}


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

回答

從技術(shù)上說(shuō),你的程序員朋友是對(duì)的,但是在大多數(shù)情況下,兩者實(shí)際上沒(méi)有區(qū)別。有兩個(gè)原因使得我們選擇第二種語(yǔ)法,它被稱(chēng)為成員初始化列表:一個(gè)原因是必須的,另一個(gè)只是出于效率考慮。

讓我們先看一下第一個(gè)原因——必要性。設(shè)想你有一個(gè)類(lèi)成員,它本身是一個(gè)類(lèi)或者結(jié)構(gòu),而且只有一個(gè)帶一個(gè)參數(shù)的構(gòu)造函數(shù)。

復(fù)制代碼 代碼如下:

class CMember {

public:

    CMember(int x) { ... }

};


因?yàn)镃member有一個(gè)顯式聲明的構(gòu)造函數(shù),編譯器不產(chǎn)生一個(gè)缺省構(gòu)造函數(shù)(不帶參數(shù)),所以沒(méi)有一個(gè)整數(shù)就無(wú)法創(chuàng)建Cmember的一個(gè)實(shí)例。

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

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

復(fù)制代碼 代碼如下:

class CMyClass {

    CMember m_member;

public:

    CMyClass();

};

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

CMyClass::CMyClass() : m_member(2)

{

•••

}


沒(méi)有其它辦法將參數(shù)傳遞給m_member,如果成員是一個(gè)常量對(duì)象或者引用也是一樣。根據(jù)C++的規(guī)則,常量對(duì)象和引用不能被賦值,它們只能被初始化。

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

復(fù)制代碼 代碼如下:

CMyClass::CMyClass() {

    // 使用賦值操作符

    // CString::operator=(LPCTSTR);

    m_str = _T("yada yada");

}

//使用類(lèi)成員列表

// and constructor CString::CString(LPCTSTR)

CMyClass::CMyClass() : m_str(_T("yada yada"))

{

}


在 它們之間有什么不同嗎?是的。編譯器總是確保所有成員對(duì)象在構(gòu)造函數(shù)體執(zhí)行之前初始化,因此在第一個(gè)例子中編譯的代碼將調(diào)用CString:: Cstring來(lái)初始化m_str,這在控制到達(dá)賦值語(yǔ)句前完成。在第二個(gè)例子中編譯器產(chǎn)生一個(gè)對(duì)CString:: CString(LPCTSTR)的調(diào)用并將"yada yada"傳遞給這個(gè)函數(shù)。結(jié)果是在第一個(gè)例子中調(diào)用了兩個(gè)Cstring函數(shù)(構(gòu)造函數(shù)和賦值操作符),而在第二個(gè)例子中只調(diào)用了一個(gè)函數(shù)。在 Cstring的例子里這是無(wú)所謂的,因?yàn)槿笔?gòu)造函數(shù)是內(nèi)聯(lián)的,Cstring只是在需要時(shí)為字符串分配內(nèi)存(即,當(dāng)你實(shí)際賦值時(shí))。但是,一般而言, 重復(fù)的函數(shù)調(diào)用是浪費(fèi)資源的,尤其是當(dāng)構(gòu)造函數(shù)和賦值操作符分配內(nèi)存的時(shí)候。在一些大的類(lèi)里面,你可能擁有一個(gè)構(gòu)造函數(shù)和一個(gè)賦值操作符都要調(diào)用同一個(gè)負(fù) 責(zé)分配大量?jī)?nèi)存空間的Init函數(shù)。在這種情況下,你必須使用初始化列表,以避免不要的分配兩次內(nèi)存。在內(nèi)部類(lèi)型如ints或者longs或者其它沒(méi)有構(gòu) 造函數(shù)的類(lèi)型下,在初始化列表和在構(gòu)造函數(shù)體內(nèi)賦值這兩種方法沒(méi)有性能上的差別。不管用那一種方法,都只會(huì)有一次賦值發(fā)生。有些程序員說(shuō)你應(yīng)該總是用初始 化列表以保持良好習(xí)慣,但我從沒(méi)有發(fā)現(xiàn)根據(jù)需要在這兩種方法之間轉(zhuǎn)換有什么困難。在編程風(fēng)格上,我傾向于在主體中使用賦值,因?yàn)橛懈嗟目臻g用來(lái)格式化和 添加注釋?zhuān)憧梢詫?xiě)出這樣的語(yǔ)句:x=y=z=0;

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

注意第二個(gè)片斷絕對(duì)是非面向?qū)ο蟮摹?/FONT>

當(dāng)我考慮初始化列表的問(wèn)題時(shí),有一個(gè)奇怪的特性我應(yīng)該警告你,它是關(guān)于C++初始化類(lèi)成員的,它們是按照聲明的順序初始化的,而不是按照出現(xiàn)在初始化列表中的順序。

復(fù)制代碼 代碼如下:

class CMyClass {

    CMyClass(int x, int y);

    int m_x;

    int m_y;

};

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

{

}


你可能以為上面的代碼將會(huì)首先做m_y=I,然后做m_x=m_y,最后它們有相同的值。但是編譯器先初始化m_x,然后是m_y,,因?yàn)樗鼈兪前催@樣的順 序聲明的。結(jié)果是m_x將有一個(gè)不可預(yù)測(cè)的值。我的例子設(shè)計(jì)來(lái)說(shuō)明這一點(diǎn),然而這種bug會(huì)更加自然的出現(xiàn)。有兩種方法避免它,一個(gè)是總是按照你希望它們 被初始化的順序聲明成員,第二個(gè)是,如果你決定使用初始化列表,總是按照它們聲明的順序羅列這些成員。這將有助于消除混淆。

網(wǎng)頁(yè)制作CMS教程網(wǎng)絡(luò)編程軟件編程腳本語(yǔ)言數(shù)據(jù)庫(kù)服務(wù)器

如果侵犯了您的權(quán)利,請(qǐng)與我們聯(lián)系,我們將在24小時(shí)內(nèi)進(jìn)行處理、任何非本站因素導(dǎo)致的法律后果,本站均不負(fù)任何責(zé)任。

聯(lián)系QQ:835971066 | 郵箱:835971066#qq.com(#換成@)

Copyright © 2002-2020 腳本教程網(wǎng) 版權(quán)所有