生活随笔
收集整理的這篇文章主要介紹了
C++类成员的初始化
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
分類: c/c++進(jìn)行時(shí) 2012-04-11 10:02 14697人閱讀 收藏 舉報(bào)
c++stringinitializationclass編譯器面試
1、關(guān)于構(gòu)造函數(shù)
1)用構(gòu)造函數(shù)確保初始化
對(duì)于一個(gè)空類
[cpp] view plaincopy
class?Empty?{?};?? 編譯器會(huì)自動(dòng)聲明4個(gè)默認(rèn)函數(shù):構(gòu)造函數(shù),拷貝構(gòu)造函數(shù),賦值函數(shù),析構(gòu)函數(shù)(當(dāng)然,如果不想使用自動(dòng)生成的函數(shù),就應(yīng)該明確拒絕),這些生成的函數(shù)都是public且inline。構(gòu)造函數(shù)對(duì)數(shù)據(jù)成員進(jìn)行初始化,使用未初始化值可能導(dǎo)致無(wú)法預(yù)知的錯(cuò)誤,所以,確保
每一個(gè)構(gòu)造函數(shù)都將
每一個(gè)成員初始化。
2)為什么構(gòu)造函數(shù)不能有返回值
如果有返回值,要么編譯器必須知道怎么處理返回值,要么就客戶程序員顯式調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù),這樣,還有安全性么?
3)為什么構(gòu)造函數(shù)不能為虛函數(shù)
簡(jiǎn)單來(lái)說(shuō),虛函數(shù)調(diào)用的機(jī)制,是知道接口而不知道其準(zhǔn)確對(duì)象類型的函數(shù),但是創(chuàng)建一個(gè)對(duì)象,必須知道對(duì)象的準(zhǔn)確類型;當(dāng)一個(gè)構(gòu)造函數(shù)被調(diào)用時(shí),它做的首要事情之一就是初始化它的VPTR來(lái)指向VTABLE。
4)構(gòu)造函數(shù)的一個(gè)面試題:
[cpp] view plaincopy
#include?<iostream>??using?namespace?std;????class?Base???{??private:??????int?i;??public:??????Base(int?x)??????{??????????i?=?x;??????}??};????class?Derived?:?public?Base??{??private:??????int?i;??public:??????Derived(int?x,?int?y)??????{??????????i?=?x;??????}??????void?print()??????{??????????cout?<<?i?+?Base::i?<<?endl;??????}??};????int?main()??{??????Derived?A(2,3);??????A.print();??????return?0;??}?? 首先,是訪問權(quán)限問題,子類中直接訪問Base::i是不允許的,應(yīng)該將父類的改為protected或者public(最好用protected)
其次,統(tǒng)計(jì)父類和子類i的和,但是通過子類構(gòu)造函數(shù)沒有對(duì)父類變量進(jìn)行初始化;此處編譯會(huì)找不到構(gòu)造函數(shù),因?yàn)樽宇愓{(diào)用構(gòu)造函數(shù)會(huì)先找父類構(gòu)造函數(shù),但是沒有2個(gè)參數(shù)的,所以可以在初始化列表中調(diào)用父類構(gòu)造函數(shù)
最后個(gè)問題,是單參數(shù)的構(gòu)造函數(shù),可能存在隱式轉(zhuǎn)換的問題,因?yàn)閱螀?shù)構(gòu)造函數(shù),和拷貝構(gòu)造函數(shù)形式類似,調(diào)用時(shí)很可能會(huì)發(fā)生隱式轉(zhuǎn)換,應(yīng)加上explicit關(guān)鍵字,修改后如下(程序員面試寶典上只改了前2個(gè))
[cpp] view plaincopy
#include?<iostream>??using?namespace?std;????class?Base???{??protected:??????int?i;??public:??????explicit?Base(int?x)??????{??????????i?=?x;??????}??};????class?Derived?:?public?Base??{??private:??????int?i;??public:??????Derived(int?x,?int?y):Base(x)??????{??????????i?=?y;??????}??????void?print()??????{??????????cout?<<?i?+?Base::i?<<?endl;??????}??};????int?main()??{??????Derived?A(2,3);??????A.print();??????return?0;??}?? 2、初始化列表
1)使用初始化列表提高效率
常用的初始化可能如下:
[cpp] view plaincopy
class?Student???{??public:??????Student(string?in_name,?int?in_age)??????{??????????name?=?in_name;??????????age?=?in_age;??????}??private?:??????string?name;??????int????age;??};?? ? ? 以前樓主也習(xí)慣這么寫,可以達(dá)到預(yù)期效果,不過不是最佳做法,因?yàn)樵跇?gòu)造函數(shù)中,是對(duì)name進(jìn)行賦值,
不是初始化,而string對(duì)象會(huì)先調(diào)用它的默認(rèn)構(gòu)造函數(shù),再調(diào)用string類(貌似是basic_string類)的賦值構(gòu)造函數(shù);對(duì)于上例的age,因?yàn)閕nt是內(nèi)置類型,應(yīng)該是賦值的時(shí)候獲得了初值。
? ? 要對(duì)成員進(jìn)行初始化,而不是賦值,可以采用初始化列表(member initialization list)改寫為如下:
[cpp] view plaincopy
class?Student???{??public:??????Student(string?in_name,?int?in_age):name(in_name),age(in_age)?{}??private?:??????string?name;??????int????age;??};?? ? ? 結(jié)果與上例相同,不過在初始化的時(shí)候調(diào)用的是string的拷貝構(gòu)造函數(shù),而上例會(huì)調(diào)用兩次構(gòu)造函數(shù),從性能上會(huì)有不小提升
? ? 有的情況下,是必須使用初始化列表進(jìn)行初始化的:const對(duì)象、引用對(duì)象
2)初始化列表初始順序
考慮以下代碼:
[cpp] view plaincopy
#include?<iostream>??using?namespace?std;????class?Base???{??public:??????Base(int?i)?:?m_j(i),?m_i(m_j)?{}??????Base()?:?m_j(0),?m_i(m_j)?{}??????int?get_i()?const??????{??????????return?m_i;??????}??????int?get_j()?const??????{??????????return?m_j;??????}????private:??????int?m_i;??????int?m_j;????};????int?main()??{??????Base?obj(98);??????cout?<<?obj.get_i()?<<?endl?<<?obj.get_j()?<<?endl;??????return?0;??}?? ? ? ?
輸出為一個(gè)隨機(jī)數(shù)和98,為什么呢?因?yàn)閷?duì)于初始化列表而言,對(duì)成員變量的初始化,是嚴(yán)格按照聲明次序,而不是在初始化列表中的順序進(jìn)行初始化,如果改為賦值初始化則不會(huì)出現(xiàn)這個(gè)問題,當(dāng)然,為了使用初始化列表,還是嚴(yán)格注意聲明順序吧,比如先聲明數(shù)組大小,再聲明數(shù)組這樣。
總結(jié)完畢,望有用
總結(jié)
以上是生活随笔為你收集整理的C++类成员的初始化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。