當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 學(xué)習(xí)筆記 > 嵌入式學(xué)習(xí)筆記:類與封裝基礎(chǔ)入門知識分享
c++是學(xué)習(xí)任何一門IT技術(shù)都必須要學(xué)的,在c++的學(xué)習(xí)重點(diǎn)和難點(diǎn)也就是類與封裝了,在這里我這只老鳥總結(jié)出了一些類與封裝基礎(chǔ),比較全面,對c++類與封裝的入門學(xué)習(xí)必備。
一、如何定義類
定義一個類,本質(zhì)上是定義一個數(shù)據(jù)類型的藍(lán)圖。這實(shí)際上并沒有定義任何數(shù)據(jù),但它定義了類的名稱意味著什么,也就是說,它定義了類的對象包括了什么,以及可以在這個對象上執(zhí)行哪些操作。
類定義是以關(guān)鍵字 class 開頭,后跟類的名稱。類的主體是包含在一對花括號中。類定義后必須跟著一個分號或一個聲明列表。
class 類名
{
成員。。。。
};
訪問限定符:
private: 私有成員變量或函數(shù)在類的外部是不可訪問的,甚至是不可查看的。只有類和友元函數(shù)可以訪問私有成員。
public: 公有成員在程序中類的外部是可訪問的?梢圆皇褂萌魏纬蓡T
函數(shù)來設(shè)置和獲取公有變量的值
protected:保護(hù)成員變量或函數(shù)與私有成員十分相似,但有一點(diǎn)不
同,保護(hù)成員在派生類(即子類)中是可訪問的。
什么是類的內(nèi)部和類的外部?
在類的作用域范圍內(nèi)叫類的內(nèi)部,在類的作用域訪問外叫類的外部
注意:定義類的時候,類的成員函數(shù)可以在類的內(nèi)部聲明,在類的外部定義,在外部定義的時候需要加作用域。
在表示數(shù)據(jù)類型的時候,class可以省略,直接用類名表示數(shù)據(jù)類型。
class 和struct 有什么區(qū)別?
在不加訪問限定符的情況下,class的成員默認(rèn)是私有屬性,struct 的成員默認(rèn)是公有屬性。
對象和類的關(guān)系:
類是某一事物的抽象,類是數(shù)據(jù)類型,對象是類的實(shí)例化,對象是變量名。
二、this指針
this指針默認(rèn)在非靜態(tài)的成員函數(shù)中存在。
指向當(dāng)前對象的首地址,誰調(diào)用該成員函數(shù),誰就是當(dāng)前對象。this指針在表示成員變量的時候可以省略
三、構(gòu)造函數(shù)
作用:初始化成員變量,初始化只會進(jìn)行一次,所以任何一個對象只會
調(diào)用一次構(gòu)造函數(shù)
特點(diǎn):
1.函數(shù)名和類名一樣
2.沒有返回值
3.可以重載
4.如果沒有自定義構(gòu)造函數(shù),編譯器會提供默認(rèn)的構(gòu)造函數(shù)進(jìn)行初始化工作
5.如果自定義構(gòu)造函數(shù),對象初始化不會調(diào)用默認(rèn)的構(gòu)造函數(shù),而是調(diào)用自定義的構(gòu)造函數(shù)
6.構(gòu)造函數(shù)不需要主動調(diào)用,創(chuàng)建對象的時候會自動調(diào)用構(gòu)造函數(shù)進(jìn)行初始化
7.構(gòu)造函數(shù)可以用初始化列表進(jìn)行初始化
8.構(gòu)造函數(shù)通常是公有的,如果是非公有將無法創(chuàng)建對象
默認(rèn)構(gòu)造函數(shù)無入?yún),無打印。
拷貝(復(fù)制)構(gòu)造函數(shù) copy construct function
作用:用一個已經(jīng)存在的對象給新創(chuàng)建的對象初始化。有默認(rèn)的拷貝構(gòu)造函數(shù),如果沒有自定義,就用默認(rèn)的。如果自定義拷貝構(gòu)造函數(shù),只會調(diào)用自定義的拷貝構(gòu)造函數(shù)默認(rèn)構(gòu)造函數(shù)屬于淺拷貝
深拷貝和淺拷貝
淺拷貝: 棧內(nèi)存之間數(shù)據(jù)的拷貝
深拷貝: 堆內(nèi)存之間數(shù)據(jù)的拷貝四、析構(gòu)函數(shù)
作用:在對象生命周期結(jié)束的時候,回收對象的資源(內(nèi)存)
特點(diǎn):
1.函數(shù)名是類名前加~
2.沒有返回值
3.沒有入?yún),不能進(jìn)行函數(shù)重載
4.如果沒有自定義析構(gòu)函數(shù),編譯器會提供默認(rèn)的析構(gòu)函數(shù)(默認(rèn)析構(gòu)函數(shù)無打印,且只會釋放棧內(nèi)存空間)
5.如果自定義析構(gòu)函數(shù),不會用默認(rèn)的析構(gòu)函數(shù),只會用自定義的析構(gòu)函數(shù)
6.析構(gòu)函數(shù)不需要主動調(diào)用,在對象生命周期結(jié)束的時候自動調(diào)用
7.如果主動調(diào)用析構(gòu)函數(shù),只是執(zhí)行析構(gòu)函數(shù)體中的內(nèi)容,并不會改變對象的生命周期。
構(gòu)造函數(shù)和析構(gòu)函數(shù)的順序?
構(gòu)造函數(shù)按照程序執(zhí)行的順序進(jìn)行構(gòu)造。
析構(gòu)函數(shù)的執(zhí)行順序由對象的生命周期來決定:
堆內(nèi)存的數(shù)據(jù)是人為釋放,當(dāng)你忘了人為釋放時在程序結(jié)束后會自動釋放;
棧的內(nèi)存在函數(shù)結(jié)束以后就釋放,析構(gòu)函數(shù)的順序和構(gòu)造函數(shù)相反。
靜態(tài)數(shù)據(jù)區(qū)的內(nèi)存在程序結(jié)束以后才釋放,同樣和構(gòu)造的順序相反。
對象的內(nèi)存空間有多大?
等于對象的成員變量的內(nèi)存大小之和(滿足字節(jié)對齊)當(dāng)對象沒有成員變量,對象的內(nèi)存大小為1個字節(jié)
總結(jié):
定義一個類,默認(rèn)有哪些成員函數(shù)和運(yùn)算符可以直接使用?1.構(gòu)造函數(shù)
2.析構(gòu)函數(shù)
3.拷貝構(gòu)造函數(shù)
4.賦值運(yùn)算符
5.&取地址運(yùn)算符
四、靜態(tài)成員
加上static修飾的成員叫靜態(tài)成員,特點(diǎn):屬于該類的所有對象共享的
1.靜態(tài)成員變量 本質(zhì)上是全局變量,所以需要在全局范圍聲明,靜態(tài)成員變量的內(nèi)存在靜態(tài)數(shù)據(jù)區(qū),只有一份,不在對象的內(nèi)存空間內(nèi)。
2.靜態(tài)成員函數(shù) 可以通過類名::函數(shù)名,直接調(diào)用靜態(tài)成員函數(shù),靜態(tài)成員函數(shù)沒有this指針。靜態(tài)成員函數(shù)訪問不了非靜態(tài)的成員變量非靜態(tài)成員函數(shù)可以訪問靜態(tài)成員變量
五、只讀成員
被const修飾的成員叫只讀成員,只讀成員只能讀不能寫,不能做左值。
1.只讀成員變量 在初始化的時候只能用初始化列表
2.只讀成員函數(shù) 不能修改成員變量的值。只讀成員函數(shù)不能調(diào)用非只讀的成員函數(shù),非只讀的成員函數(shù)可以調(diào)用只讀的成員函數(shù)
3.只讀對象 該對象只能讀不能寫 mutable 關(guān)鍵字 (可變的)
被mutable修飾的變量不受const的約束三、友元
類的好友叫友元。友元可以訪問類的私有成員。
1.外部函數(shù)是友元 ***** 該外部函數(shù)可以訪問本類的私有成員
2.外部類是友元 *** 外部友元類的所有成員函數(shù)都可以訪問本類的私有成員
3.外部類的成員函數(shù)是友元 *** 只有聲明為友元的成員函數(shù)可以訪問本類的私有成員,其他的成員函數(shù)不行
友元具不具有傳遞性?
友元不具有傳遞性
友元的聲明不受訪問限定符的影響?偨Y(jié)什么是封裝,封裝有什么作用?
1.定義類,類中有數(shù)據(jù)和方法,模塊化編程,提高編程的效率。
2.通過訪問限定符,確定哪些成員是隱藏的,哪些是暴露在外的接口,為了數(shù)據(jù)安全性。
友元破壞了封裝,需要謹(jǐn)慎使用。
六、運(yùn)算符重載
為什么要進(jìn)行運(yùn)算符重載?
1.運(yùn)算符只對基本數(shù)據(jù)類型有效,對自定義的類類型無效。對象之間的運(yùn)算必須要進(jìn)行運(yùn)算符重載
2.使用用運(yùn)算符重載,使對象之間的運(yùn)算變得簡單,方便。
大部分運(yùn)算符都可以被重載,只有如下不能:
成員運(yùn)算符. 三目運(yùn)算符?: sizeof運(yùn)算符 作用域運(yùn)算符::
運(yùn)算符重載的本質(zhì)是特殊的函數(shù):(函數(shù)名特殊)
返回值類型 operator 運(yùn)算符(入?yún)⒘斜怼!!?
{
函數(shù)體。。。。
}
類有哪些函數(shù):
1.成員函數(shù) 類的組成部分,可以訪問類的私有成員,有this指針指代當(dāng)前對象
2.友元函數(shù) 不是類的組成部分,可以類訪問私有成員,沒有this指針
3.非友元的外部函數(shù) 不能訪問類的私有成員成員函數(shù)和友元函數(shù)做運(yùn)算符重載有什么區(qū)別?
友元函數(shù)比成員函數(shù)做相同的運(yùn)算符重載多一個入?yún)。原因:成員函數(shù)有this指針可以指代一個對象。
注意:運(yùn)算符重載不能改變運(yùn)算符的優(yōu)先級和含義。
七、數(shù)據(jù)封裝
所有的 C++ 程序都有以下兩個基本要素:
程序語句(代碼):這是程序中執(zhí)行動作的部分,它們被稱為函數(shù)。
程序數(shù)據(jù):數(shù)據(jù)是程序的信息,會受到程序函數(shù)的影響。
封裝是面向?qū)ο缶幊讨械陌褦?shù)據(jù)和操作數(shù)據(jù)的函數(shù)綁定在一起的一個概念,這樣能避免受到外界的干擾和誤用,從而確保了安全。數(shù)據(jù)封裝引申出了另一個重要的 OOP 概念,即數(shù)據(jù)隱藏。
數(shù)據(jù)封裝是一種把數(shù)據(jù)和操作數(shù)據(jù)的函數(shù)捆綁在一起的機(jī)制,數(shù)據(jù)抽象是一種僅向用戶暴露接口而把具體的實(shí)現(xiàn)細(xì)節(jié)隱藏起來的機(jī)制。數(shù)據(jù)抽象
數(shù)據(jù)抽象是指,只向外界提供關(guān)鍵信息,并隱藏其后臺的實(shí)現(xiàn)細(xì)節(jié),即只表現(xiàn)必要的信息而不呈現(xiàn)細(xì)節(jié)。
數(shù)據(jù)抽象是一種依賴于接口和實(shí)現(xiàn)分離的編程(設(shè)計(jì))技術(shù)。
舉一個現(xiàn)實(shí)生活中的真實(shí)例子,比如一臺電視機(jī),您可以打開和關(guān)閉、切換頻道、調(diào)整音量、添加外部組件(如喇叭、錄像機(jī)、DVD 播放器),但是您不知道它的內(nèi)部實(shí)現(xiàn)細(xì)節(jié),也就是說,您并不知道它是如何通過纜線接收信號,如何轉(zhuǎn)換信號,并最終顯示在屏幕上。
因此,我們可以說電視把它的內(nèi)部實(shí)現(xiàn)和外部接口分離開了,您無需知道它的內(nèi)部實(shí)現(xiàn)原理,直接通過它的外部接口(比如電源按鈕、遙控器、聲量控制器)就可以操控電視。
數(shù)據(jù)抽象的好處
數(shù)據(jù)抽象有兩個重要的優(yōu)勢:
類的內(nèi)部受到保護(hù),不會因無意的用戶級錯誤導(dǎo)致對象狀態(tài)受損。類實(shí)現(xiàn)可能隨著時間的推移而發(fā)生變化,以便應(yīng)對不斷變化的需求,或者應(yīng)對那些要求不改變用戶級代碼的錯誤報(bào)告。
如果只在類的私有部分定義數(shù)據(jù)成員,編寫該類的作者就可以隨意更改數(shù)據(jù)。如果實(shí)現(xiàn)發(fā)生改變,則只需要檢查類的代碼,看看這個改變會導(dǎo)致哪些影響。如果數(shù)據(jù)是公有的,則任何直接訪問舊表示形式的數(shù)據(jù)成員的函數(shù)都可能受到影響。