c 类别构造函数需要包含所有成员吗_C++默认成员函数解析
1.什么是面向?qū)ο?#xff1f;
概念:(Object Oriented Programming,縮寫:OOP)是一種程序設(shè)計(jì)范型,同時(shí)也是一種程序開發(fā)的方法。
對(duì)象指的是類的實(shí)例,將對(duì)象作為程序的基本單元,將程序和數(shù)據(jù)封裝其中,以提高軟件的重用性、靈活性和擴(kuò)展性。
C++不是純面向?qū)ο笳Z言,而是基于面向?qū)ο蟮恼Z言
(ps:因?yàn)樗珻的部分,C是面向過程)
面向?qū)ο笕筇匦?#xff1a;封裝、繼承、多態(tài)
2.類的大小?為什么要內(nèi)存對(duì)齊?內(nèi)存對(duì)齊的計(jì)算?空類的計(jì)算
①類的大小(是不是很疑惑,類腫么還有大小,不就是個(gè)類型嘛,納尼)
是的類有大小,看個(gè)栗子:
class Book { public: Book(); voidShow( ); private: charname[10]; intisbn; };
sizeof(Book);會(huì)是多少?
有沒有算出來。
其實(shí)類和我們結(jié)構(gòu)體一樣是有大小的,而且類的內(nèi)存對(duì)齊方式和結(jié)構(gòu)體一樣。
②為什么要內(nèi)存對(duì)齊?
這個(gè)要說到操作系統(tǒng)上了,我們的cpu把內(nèi)存當(dāng)成是一塊一塊的,塊的大小可以是2,4,8,16 個(gè)字節(jié),因此CPU在讀取內(nèi)存的時(shí)候是一塊一塊進(jìn)行讀取的,塊的大小稱為(memory granularity)內(nèi)存讀取粒度。
為什么要分塊呢?(分塊讀取有利于提高內(nèi)存訪問效率)
和內(nèi)存對(duì)齊有什么關(guān)系?
假設(shè)CPU要讀取一個(gè)4字節(jié)大小的數(shù)據(jù)到寄存器中(假設(shè)內(nèi)存讀取粒度是4),分兩種情況討論:
1.數(shù)據(jù)從0字節(jié)開始
2.數(shù)據(jù)從1字節(jié)開始
解析:當(dāng)數(shù)據(jù)從0字節(jié)開始的時(shí)候,直接將0-3四個(gè)字節(jié)完全讀取到寄存器,結(jié)算完成了。當(dāng)數(shù)據(jù)從1字節(jié)開始的時(shí)候,問題很復(fù)雜,首先先將前4個(gè)字節(jié)讀到寄存器,并再次讀取4-7字節(jié)的數(shù)據(jù)進(jìn)寄存器,接著把0字節(jié),4,6,7字節(jié)的數(shù)據(jù)剔除,最后合并1,2,3,4字節(jié)的數(shù)據(jù)進(jìn)寄存器,對(duì)一個(gè)內(nèi)存未對(duì)齊的寄存器進(jìn)行了這么多額外操作,大大降低了CPU的性能。
所以內(nèi)存對(duì)齊就很好的提高了cpu的讀取效率。
內(nèi)存對(duì)齊的計(jì)算?
1.第一個(gè)成員在與結(jié)構(gòu)體變量偏移量為0的地址處。
2.其他成員變量要對(duì)齊到某個(gè)數(shù)字(對(duì)齊數(shù))的整數(shù)倍的地址處。
對(duì)齊數(shù) = 編譯器默認(rèn)的一個(gè)對(duì)齊數(shù) 與 該成員大小的較小值。
VS中默認(rèn)的值為8
gcc中的默認(rèn)值為4
3.結(jié)構(gòu)體總大小為最大對(duì)齊數(shù)(每個(gè)成員變量除了第一個(gè)成員都有一個(gè)對(duì)齊數(shù))的整數(shù)倍。
4.如果嵌套了結(jié)構(gòu)體的情況,嵌套的結(jié)構(gòu)體對(duì)齊到自己的最大對(duì)齊數(shù)的整數(shù)倍處,結(jié)構(gòu)體的整體大小就是所有最大對(duì)齊數(shù)(含嵌套結(jié)構(gòu)體的對(duì)齊數(shù))的整數(shù)倍。
空類的計(jì)算
先說答案:空類的大小是1
3.類的6個(gè)默認(rèn)成員函數(shù)的詳細(xì)使用及細(xì)節(jié)
c++的類有六個(gè)默認(rèn)成員函數(shù):
我們常用的是前四個(gè)。
1)構(gòu)造函數(shù):
成員變量為私有的,要對(duì)它們進(jìn)行初始化,必須用一個(gè)公有成員函數(shù)來進(jìn)行。同時(shí)這個(gè)函數(shù)應(yīng)該有且僅在定義對(duì)象時(shí)自動(dòng)執(zhí)行一次,這時(shí)調(diào)用的函數(shù)稱為構(gòu)造函數(shù)(constructor) 。
構(gòu)造函數(shù)是特殊的成員函數(shù),其特征如圖:
構(gòu)造函數(shù)基本我們都使用全缺省的重載函數(shù)。
2)拷貝構(gòu)造函數(shù):
創(chuàng)建對(duì)象時(shí)使用同類對(duì)象來進(jìn)行初始化,這時(shí)所用的構(gòu)造函數(shù)稱為拷貝構(gòu)造函數(shù)(Copy Constructor),拷貝構(gòu)造函數(shù)是特殊的構(gòu)造函數(shù)。
來個(gè)例子:
class Book { public: Book( ); Book( intisbn = 0x00, char*name = "圖書"); private: intisbn; char*name; }; intmain( ) { Book b( ); Book b1(b); //這里使用了拷貝構(gòu)造system( "pause"); return0; }
特征:
?拷貝構(gòu)造函數(shù)其實(shí)是一個(gè)構(gòu)造函數(shù)的重載。
?拷貝構(gòu)造函數(shù)的參數(shù)必須使用引用傳參,使用傳值方式會(huì)引發(fā)無窮遞歸調(diào)用。(思考為什么?)
?若未顯示定義,系統(tǒng)會(huì)默認(rèn)缺省的拷貝構(gòu)造函數(shù)。缺省的拷貝構(gòu)造函數(shù)會(huì),依次拷貝類成員進(jìn)行初始化。
一般情況下我們會(huì)使用系統(tǒng)默認(rèn)的拷貝構(gòu)造函數(shù),但是在特殊情況下需要顯示定義(比如鏈表的拷貝構(gòu)造)
3)析構(gòu)函數(shù)
當(dāng)一個(gè)對(duì)象的生命周期結(jié)束時(shí),C++編譯系統(tǒng)會(huì)自動(dòng)調(diào)用一個(gè)成員函數(shù),這個(gè)特殊的成員函數(shù)即析構(gòu)函數(shù)(destructor)
構(gòu)造函數(shù)是特殊的成員函數(shù),其特征如下:
?析構(gòu)函數(shù)在類名加上字符~。
?析構(gòu)函數(shù)無參數(shù)無返回值。
?一個(gè)類有且只有一個(gè)析構(gòu)函數(shù)。若未顯示定義,系統(tǒng)會(huì)自動(dòng)生成缺省的析構(gòu)函數(shù)。
?對(duì)象生命周期結(jié)束時(shí),C++編譯系統(tǒng)系統(tǒng)自動(dòng)調(diào)用析構(gòu)函數(shù)。
?注意析構(gòu)函數(shù)體內(nèi)并不是刪除對(duì)象,而是做一些清理工作。(怎么理解這里的清理工作?參看下面的代碼)
class Date { public: // 析構(gòu)函數(shù) ~ Date() {} private: int_year ; int_month ; int_day ; }; class Array { public: Array( intsize) { _ptr = ( int*)malloc( size* sizeof( int)); } // 這里的析構(gòu)函數(shù)需要完成清(shi)理(fang)工(kong)作(jian)。~ Array () { if(_ptr ) { free(_ptr ); _ptr = 0; } } private: int* _ptr ; };
4)賦值操作符重載
為了增強(qiáng)程序的可讀性,C++支持運(yùn)算符重載。
運(yùn)算符重載特征:
?operator+ 合法的運(yùn)算符 構(gòu)成函數(shù)名(重載
?重載運(yùn)算符以后,不能改變運(yùn)算符的優(yōu)先級(jí)/結(jié)合性/操作數(shù)個(gè)數(shù)。
5個(gè)C++不能重載的運(yùn)算符: .*/::/sizeof/?:/.
5)取地址操作符重載
class Date { public: Date* operator&() { returnthis; } constDate * operator&() const{ returnthis; } private: int_year ; // 年int_month ; // 月int_day ; // 日};
6)const修飾的取地址操作符函數(shù)
在成員函數(shù)后面加const,const修飾this指針?biāo)赶虻膶?duì)象,也就是保證調(diào)用這個(gè)const成員函數(shù)的對(duì)象在函數(shù)內(nèi)不會(huì)被改變。
classDate { public: voidDisplay () { cout<< "Display ()"<
后兩個(gè)成員函數(shù)用的很少。
最后,學(xué)習(xí)從來不是一個(gè)人的事情,要有個(gè)相互監(jiān)督的伙伴,對(duì)于C/C++感興趣可以關(guān)注小編在后臺(tái)私信我:【編程】一起來學(xué)習(xí)哦!可以領(lǐng)取一些C/C++的項(xiàng)目學(xué)習(xí)視頻資料哦!已經(jīng)設(shè)置好了關(guān)鍵詞自動(dòng)回復(fù),自動(dòng)領(lǐng)取就好了
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的c 类别构造函数需要包含所有成员吗_C++默认成员函数解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: delphi socket 流的使用_S
- 下一篇: 学C/C++语言,32个必备修养!