目錄
樂都ssl適用于網(wǎng)站、小程序/APP、API接口等需要進行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)公司的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18982081108(備注:SSL證書合作)期待與您的合作!1.面向過程和面向?qū)ο蟪醪秸J識
2.類的引入
3.類的定義
類的兩種定義方式:
4.類的訪問限定符及封裝
4.1 訪問限定符
4.2 封裝
封裝
封裝的意義
對象封裝原則
5.類的作用域
6.類的實例化
7.類對象模型
8.this指針
8.1 this指針的引出
8.2 this指針的特性
? (1)C語言是面向過程的,關(guān)注的是過程,分析出求解問題的步驟,通過函數(shù)調(diào)用逐步解決問題。
比如:現(xiàn)在我要洗個衣服,我需要:拿個盆子、放水、放衣服、放洗衣粉、手搓、放洗衣粉、換水、手搓、擰干、晾衣服,這些是每一個具體的步驟
?(2)C++是基于面向?qū)ο蟮?,關(guān)注的是對象,將一件事情拆分成不同的對象,靠對象之間的交互完成。?我們不需要考慮其中具體過程,經(jīng)過別的物品之手完成此事便可
還是洗衣服:面向?qū)ο蟮慕忉專?/p>
2.類的引入? C語言結(jié)構(gòu)體中只能定義變量,在C++中,結(jié)構(gòu)體內(nèi)不僅可以定義變量,也可以定義函數(shù)。比如:之前在數(shù)據(jù)結(jié)構(gòu)初階中,用C語言方式實現(xiàn)的棧,結(jié)構(gòu)體中只能定義變量;現(xiàn)在以C++方式實現(xiàn),會發(fā)現(xiàn)struct中也可以定義函數(shù)。(c++是兼容c語言的,在c++中一般使用class來定義類,class和struct有許多不同)
3.類的定義? class為定義類的關(guān)鍵字,ClassName為類的名字,{}中為類的主體,注意類定義結(jié)束時后面分號不能省略。
class className{
// 類體:由成員函數(shù)和成員變量組成
}; // 一定要注意后面的分號
類體中內(nèi)容稱為類的成員:類中的變量稱為類的屬性或成員變量; 類中的函數(shù)稱為類的方法或者成員函數(shù)。
類的兩種定義方式:?1. 聲明和定義全部放在類體中,需注意:成員函數(shù)如果在類中定義,編譯器可能會將其當(dāng)成內(nèi)聯(lián)函數(shù)處理。
2. 類聲明放在.h文件中,成員函數(shù)定義放在.cpp文件中,注意:成員函數(shù)名前需要加類名? ?::
? 一般情況下,更期望采用第二種方式。注意:上課為了方便演示使用方式一定義類,大家后序工作中盡量使用第二種。
4.類的訪問限定符及封裝 4.1 訪問限定符【?訪問限定符說明】
1. public修飾的成員在類外可以直接被訪問
2. protected和private修飾的成員在類外不能直接被訪問(此處protected和private是類似的)
3. 訪問權(quán)限作用域從該訪問限定符出現(xiàn)的位置開始直到下一個訪問限定符出現(xiàn)時為止
4. 如果后面沒有訪問限定符,作用域就到? ?}? 即類結(jié)束。
5. class的默認訪問權(quán)限為private,struct為public(因為struct要兼容C)
注意:訪問限定符只在編譯時有用,當(dāng)數(shù)據(jù)映射到內(nèi)存后,沒有任何訪問限定符上的區(qū)別
C++中struct和class的區(qū)別是什么?
??解答:C++需要兼容C語言,所以C++中struct可以當(dāng)成結(jié)構(gòu)體使用。另外C++中struct還可以用來定義類。和class定義類是一樣的,區(qū)別是struct定義的類默認訪問權(quán)限是public,class定義的類默認訪問權(quán)限是private。注意:在繼承和模板參數(shù)列表位置,struct和class也有區(qū)別,class可以創(chuàng)建生成模板,而c++不可以。
C++實現(xiàn)封裝的方式:用類將對象的屬性與方法結(jié)合在一塊,讓對象更加完善,通過訪問權(quán)限選擇性的將其接口提供給外部的用戶使用。
4.2 封裝面向?qū)ο蟮娜筇匦裕悍庋b、繼承、多態(tài)。
封裝?封裝是將數(shù)據(jù)和操作數(shù)據(jù)的方法進行有機結(jié)合,隱藏對象的屬性和實現(xiàn)細節(jié),僅對外公開接口來和對象進行交互。
(1)封裝是實現(xiàn)面向?qū)ο蟮牡谝徊剑庋b就是將數(shù)據(jù)或函數(shù)等集合在一個單元中(類)。被封裝的對象通常被稱為抽象數(shù)據(jù)類型。
(2)類具有封裝性,類能夠把數(shù)據(jù)和算法(操作數(shù)據(jù)的函數(shù))組合在一起,構(gòu)成一個不可分割的整體;
(3)類具有信息隱藏的能力,它能夠有效地把類的內(nèi)部數(shù)據(jù)(即私有和受保護成員)隱藏起來,使外部函數(shù)只能通過類的公有成員才能訪問類的內(nèi)部數(shù)據(jù),并且控制訪問級別。
封裝使類成為一個具有內(nèi)部數(shù)據(jù)的自我隱藏能力、功能獨立的軟件模塊封裝本質(zhì)上是一種管理,讓用戶更方便使用類。比如:對于電腦這樣一個復(fù)雜的設(shè)備,提供給用戶的就只有開關(guān)機鍵、通過鍵盤輸入,顯示器,USB插孔等,讓用戶和計算機進行交互,完成日常事務(wù)。但實際上電腦真正工作的卻是CPU、顯卡、內(nèi)存等一些硬件元件。
? 對于計算機使用者而言,不用關(guān)心內(nèi)部核心部件,比如主板上線路是如何布局的,CPU內(nèi)部是如何設(shè)計的等,用戶只需要知道,怎么開機、怎么通過鍵盤和鼠標(biāo)與計算機進行交互即可。因此計算機廠商在出廠時,在外部套上殼子,將內(nèi)部實現(xiàn)細節(jié)隱藏起來,僅僅對外提供開關(guān)機、鼠標(biāo)以及鍵盤插孔等,讓用戶可以與計算機進行交互即可。
?在C++語言中實現(xiàn)封裝,可以通過類將數(shù)據(jù)以及操作數(shù)據(jù)的方法進行有機結(jié)合,通過訪問權(quán)限來隱藏對象內(nèi)部實現(xiàn)細節(jié),控制哪些方法可以在類外部直接被使用。
封裝的意義對象封裝原則a)保護或防止代碼(數(shù)據(jù))在無意中被破壞。保護類中的成員,不讓類以外的程序直接訪問或修改,只能通過提供的公共接口訪問(數(shù)據(jù)封裝)
b)隱藏方法(實現(xiàn))細節(jié),只要接口不變,內(nèi)容的修改不會影響到外部的調(diào)用者(方法封裝)
c)封裝可以使對象擁有完整的屬性和方法(類中的函數(shù))
d)外部不能直接訪問對象的屬性,只能通過該屬性對應(yīng)的公有方法訪問
a)內(nèi)聚:指一個模塊(類)內(nèi)部各個部分之間的關(guān)聯(lián)程度
b) 耦合:指各個模塊(類)之間的關(guān)聯(lián)程度
總結(jié):用類實現(xiàn)封裝,用封裝來實現(xiàn)高內(nèi)聚,低耦合
5.類的作用域類定義了一個新的作用域,類的所有成員都在類的作用域中。在類體外定義成員時,需要使用 :: 作用域操作符指明成員屬于哪個類域。
6.類的實例化用類類型創(chuàng)建對象的過程,稱為類的實例化
1. 類是對對象進行描述的,是一個模型一樣的東西,限定了類有哪些成員,定義出一個類并沒有分配實際的內(nèi)存空間來存儲它;比如:入學(xué)時填寫的學(xué)生信息表,表格就可以看成是一個類,來描述具體學(xué)生信息。
2. 一個類可以實例化出多個對象,實例化出的對象 占用實際的物理空間,存儲類成員變量
int main() {
Person._age = 100; // 編譯失?。篹rror C2059: 語法錯誤:“.”4
return 0;
}
?在上面這一段代碼當(dāng)中,Person類是沒有空間的,只有Person類實例化出的對象才有具體的年齡。
3. 做個比方。類實例化出對象就像現(xiàn)實中使用建筑設(shè)計圖建造出房子,類就像是設(shè)計圖,只設(shè)計出需要什么東西,但是并沒有實體的建筑存在,同樣類也只是一個設(shè)計,實例化出的對象才能實際存儲數(shù)據(jù),占用物理空間
7.類對象模型問:如何計算類對象的大???
(1)類對象的存儲方式猜測
?對象中包含類的各個成員
??缺陷:每個對象中成員變量是不同的,但是調(diào)用同一份函數(shù),如果按照此種方式存儲,當(dāng)一個類創(chuàng)建多個對象時,每個對象中都會保存一份代碼,相同代碼保存多次,浪費空間。那么如何解決呢?
?代碼只保存一份,在對象中保存存放代碼的地址
只保存成員變量,成員函數(shù)存放在公共的代碼段
結(jié)論:一個類的大小,實際就是該類中”成員變量”之和,當(dāng)然要注意內(nèi)存對齊
注意空類的大小,空類比較特殊,編譯器給了空類一個字節(jié)來唯一標(biāo)識這個類的對象。(在gcc下空類為0,g++下為1進行標(biāo)識)
看下面?zhèn)z個例子:
class a{
private:
int a;
double b;
short c;
};
class b {
private:
int a;
short c;
double b;
};
為啥只是定義的前后順序不同,類的大小就不相同,這是因為內(nèi)存對齊的緣故
對結(jié)構(gòu)體A來說,a是int類型占4個字節(jié)(從0~3),b是short類型占2個字節(jié)(從4~5),c占8個字節(jié)(從8~15)。而對于對結(jié)構(gòu)體B來說,a是int類型占4個字節(jié)(從0~3),b是double類型占8個字節(jié)(從8~15),c占2個字節(jié)(從16~17)。?
?結(jié)構(gòu)體的內(nèi)存對齊規(guī)則:
??對齊規(guī)則是按照成員的聲明順序,依次安排內(nèi)存,其偏移量為成員大小的整數(shù)倍,0看做任何成員的整數(shù)倍。最后結(jié)構(gòu)體的大小為大成員的整數(shù)倍 ?(所以這里的B中,最后結(jié)構(gòu)體大小為double的倍數(shù)是24,而不是18)。
1. 第一個成員在與結(jié)構(gòu)體偏移量為0的地址處。
2. 其他成員變量要對齊到某個數(shù)字(對齊數(shù))的整數(shù)倍的地址處。
注意:對齊數(shù) = 編譯器默認的一個對齊數(shù) 與 該成員大小的較小值。
VS中默認的對齊數(shù)為8
3. 結(jié)構(gòu)體總大小為:大對齊數(shù)(所有變量類型大者與默認對齊參數(shù)取最?。┑恼麛?shù)倍。
4. 如果嵌套了結(jié)構(gòu)體的情況,嵌套的結(jié)構(gòu)體對齊到自己的大對齊數(shù)的整數(shù)倍處,結(jié)構(gòu)體的整體大小就是
所有大對齊數(shù)(含嵌套結(jié)構(gòu)體的對齊數(shù))的整數(shù)倍。
問:
1. 結(jié)構(gòu)體怎么對齊? 為什么要進行內(nèi)存對齊?
答:
(1). 平臺原因(移植原因): 不是所有的硬件平臺都能訪問任意地址上的任意數(shù)據(jù)
的;某些硬件平臺只能 在某些地址處取某些特定類型的數(shù)據(jù),否則拋出硬件異常。(2). 性能原因: 數(shù)據(jù)結(jié)構(gòu)(尤其是棧)應(yīng)該盡可能地在自然邊界上對齊。 原因在
于,為了訪問未對齊的 內(nèi)存,處理器需要作兩次內(nèi)存訪問;而對齊的內(nèi)存訪問
僅需要一次訪問。
總體來說:結(jié)構(gòu)體的內(nèi)存對齊是拿空間來換取時間的做法。優(yōu)點是提高了可移植性和cpu性能
2. 如何讓結(jié)構(gòu)體按照指定的對齊參數(shù)進行對齊?能否按照3、4、5即任意字節(jié)對齊?
設(shè)置對齊參數(shù)可在結(jié)構(gòu)體struct之前加上#pragma pack(對齊數(shù)),在struct之后加上#pragma pack;便可以設(shè)置對齊參數(shù)。
設(shè)置字節(jié)對齊一般是只支持1 2 4 8 16這種2的冪指數(shù),class和結(jié)構(gòu)體的計算方式類似
ps:Vc,Vs等編譯器默認是#pragma pack(8),所以測試我們的規(guī)則會正常;注意gcc默認是#pragma pack(4),并且gcc只支持1,2,4對齊
3. 什么是大小端?如何測試某臺機器是大端還是小端,有沒有遇到過要考慮大小端的場景
8.this指針 8.1 this指針的引出大小端是指數(shù)據(jù)在內(nèi)存中的保存方式。
顧名思義 大小端 就是大端和小端。
大端模式:
所謂的大端模式,是指數(shù)據(jù)的高字節(jié),保存在內(nèi)存的低地址中,數(shù)據(jù)的低字節(jié),保存在內(nèi)存的高地址中。
低地址存在高位,高地址存在低位。
例子:
0000430: e684 6c4e 0100 1800 53ef 0100 0100 0000
大端模式下,前32位應(yīng)該讀為:e6 84 6c 4e
例如 int a=0x12345678
大端模式下存儲為12 34 56 78
int a =10;
大端模式下為 00 00 00 0a小端模式
所謂的小端模式,是指數(shù)據(jù)的低字節(jié),保存在內(nèi)存的高地址中,數(shù)據(jù)的高字節(jié),保存在內(nèi)存的低地址中。
低地址存在低位,高地址存在高位。
例子:
0000430: e684 6c4e 0100 1800 53ef 0100 0100 0000
小端模式下,前32位應(yīng)該讀為:4e 6c 84 e6
例如 int a=0x12345678
小端模式下存儲為78 56 34 12
int a =10;
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout<<_year<< "-"<<_month<< "-"<< _day<
對于上述類,有這樣的一個問題:
Date類中有 Init 與 Print 兩個成員函數(shù),函數(shù)體中沒有關(guān)于不同對象的區(qū)分,那當(dāng)d1調(diào)用 Init 函數(shù)時,該函 數(shù)是如何知道應(yīng)該設(shè)置d1對象,而不是設(shè)置d2對象呢?
? C++中通過引入this指針解決該問題,即:C++編譯器給每個“非靜態(tài)的成員函數(shù)“增加了一個隱藏的指針參 數(shù),讓該指針指向當(dāng)前對象(函數(shù)運行時調(diào)用該函數(shù)的對象),在函數(shù)體中所有“成員變量”的操作,都是通過該 指針去訪問。只不過所有的操作對用戶是透明的,即用戶不需要來傳遞,編譯器自動完成。
8.2 this指針的特性1. this指針的類型:類類型* const,即成員函數(shù)中,不能給this指針賦值。
2. 只能在“成員函數(shù)”的內(nèi)部使用
3. this指針本質(zhì)上是“成員函數(shù)”的形參,當(dāng)對象調(diào)用成員函數(shù)時,將對象地址作為實參傳遞給this形參。 所以對象中不存儲this指針。
4. this指針是“成員函數(shù)”第一個隱含的指針形參,一般情況由編譯器通過ecx寄存器自動傳遞,不需要用 戶傳遞
問:this指針存在哪里?
答:其實編譯器在生成程序時加入了獲取對象首地址的相關(guān)代碼。并把獲取的首地址存放在了寄存器ECX中(VC++編譯器是放在ECX中,其它編譯器有可能不同)。也就是成員函數(shù)的其它參數(shù)正常都是存放在棧中。而this指針參數(shù)則是存放在寄存器中。
問:this指針可以為空嗎?
答:可以為空,當(dāng)我們在調(diào)用函數(shù)的時候,如果函數(shù)內(nèi)部并不需要使用到this,也就是不需要通過this指向當(dāng)前對象并對其進行操作時才可以為空(當(dāng)我們在其中什么都不放或者在里面隨便打印一個字符串),如果調(diào)用的函數(shù)需要指向當(dāng)前對象,并進行操作,則會發(fā)生錯誤(空指針引用)就跟C中一樣不能進行空指針的引用
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧