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