C/C++編程筆記:C++入門知識丨類和對象
本篇要學習的內容和知識結構概覽

類及其實例化
類的定義
將一組對象的共同特征抽象出來, 從而形成類的概念.
類包括數據成員和成員函數, 不能在類的聲明中對數據成員進行初始化
聲明類
形式為:

無論是數據成員還是成員函數, 都是這個類的成員, 都具有一個訪問權限, 如果沒有關鍵字進行修飾, 則默認為private權限
聲明一個類, 像這樣:

定義成員函數
形式為:
// :: 為作用域運算符, 表示這個函數屬于哪個類
返回類型 類名::成員函數名(參數列表) {
? ? 函數體 // 內部實現(xiàn)
}
我們在上面的聲明類的代碼中, 聲明了成員函數, 我們可以在類外面定義成員函數, 也就是給出函數體
像這樣:

如果在聲明類的同時, 在類體內給出成員函數的定義, 則默認為內聯(lián)函數
我們一般都是在類體內存給出成員函數的定義
像這樣, 完成一個類的聲明和定義

不能在類體內和類體外對數據數據成員賦值
像這樣是不行的:

只有產生了具體對象, 這些數據值才有意義
初始化: 在產生對象時就使對象的數據成員具有指定值, 則稱為對象的初始化
賦值: 有了對象之后, 對象調用自己的成員函數實現(xiàn)賦值操作
使用類的對象
類的成員函數可以直接使用自己類的私有成員
類外面的函數不能直接訪問類的私有成員, 而只能通過類的對象使用公有成員函數
定義類對象指針的語法: 類名 * 對象指針名 = 對象地址;
通過對象指針可以訪問對象的成員: 對象指針名 -> 對象成員名;
像這樣:

構造函數
默認構造函數
一個類如果沒有定義任何構造函數, 編譯器會自動定義一個不帶參數的構造函數, 也就是默認構造函數
比如我們有一個類Point
則默認構造函數就是這樣:Point::Point() {};
如果一個類提供了構造函數, 系統(tǒng)不再提供默認構造函數
我們有一個Point類, 像這樣:

則我們就不能在main函數中這樣使用:

我們想要這樣使用, 則必須手動添加無參數構造函數
像這樣:

定義構造函數
構造函數的名字應該與類名同名, 并在定義構造函數時不能指定返回類型, void也不可以

我們一般都在類的聲明內部進行函數定義
像這樣:

注意
不能在程序中顯式地調用構造函數, 構造函數是自動調用的
即不能這樣: Point a.Point(2, 3);
只能這樣: Point a(2, 3);
作用
用來在產生對象的同時, 進行對象的初始化
構造函數和運算符new
new用來建立生存期可控的動態(tài)對象, 返回這個對象的指針
new和構造函數一同起作用
過程: 當用new建立動態(tài)對象時, 首先分配可以保存這個類對象的內存空間, 然后自動調用構造函數來初始化這塊內存, 再返回這個動態(tài)對象的地址
使用new建立的動態(tài)對象只能使用delete刪除, 以釋放所占空間
像這樣:

構造函數的默認參數
如果我們定義了有參構造函數, 又想使用無參構造函數, 我們可以將有參構造函數的參數全部使用默認參數
像這樣:

復制構造函數
作用: 通過拷貝方式使用一個類的已有對象來建立一個該類的新對象, 一般編譯器會建立一個默認的復制構造函數
像這樣:類名(const 類名 &); // 為了不改變原有對象, 使用const來進行修飾
復制構造函數也可以自定義, 則編譯器不再調用默認的復制構造函數
像這樣:

使用復制構造函數的三種情況
當用一個類的對象去初始化另一個對象時, 需要調用復制構造函數
像這樣:

如果函數的形參是類的對象, 調用函數時, 進行形參與實參的結合時, 需要調用復制構造函數
像這樣:

如果函數的返回值是對象, 當函數調用完成返回時, 需要調用復制構造函數, 產生臨時對象, 并在執(zhí)行完返回值語句后, 析構臨時對象

函數參數使用對象的引用不產生副本, 所以當對象作為函數參數時, 推薦使用對象引用這種方式
析構函數
作用:在對象消失時, 使用析構函數釋放由構造函數分配的內存
定義析構函數
為了與構造函數區(qū)分, 在析構函數前加”~”號,
并且在定義析構函數時, 不能指定返回類型, 即使是void類型也不可以;
也不能指定參數, 但可以顯式的說明參數為void
格式: ~類名(); // 或者 ~類名(void);
代碼像這樣:?
~Point(); // 或者 ~Point(void);
析構函數在對象的生存期結束時自動調用, 然后對象占用的內存被回收
全局對象和靜態(tài)對象的析構函數在程序運行結束之前調用
類對象的數組每個元素調用一次析構函數
像這樣: 可以運行該代碼, 查看程序執(zhí)行過程


析構函數和運算符delete
當使用運算符delete刪除一個動態(tài)對象時, 首先為這個對象調用析構函數, 然后再釋放這個動態(tài)對象占用的內存
像這樣:

默認析構函數
如果沒有定義析構函數, 編譯器自動為類產生一個函數體為空的默認析構函數
像這樣:~ Point(){};
成員函數重載及默認參數
成員函數可重載或使用默認參數, 為了提高可讀性

this指針
this指針的概念和作用
當一個成員函數被調用時, 系統(tǒng)自動向該函數傳遞一個隱含的參數, 指向調用該函數的對象指針, 名為this, 從而使用成員函數知道該對哪個對象進行操作.
作用: 它將對象和該對象調用的成員函數連接在一起, 從外部看來, 每個對象都擁有自己的成員函數, 但處理這些數據成員的代碼可以被所有的對象共享
this指針的實際形式
我們一般情況下都會省略this


一個類的對象作為另一個類的成員
因為類本身就是一種新的數據類型, 所以一個類的對象可以作為另一個類的成員
像這樣:


類和對象的性質
對象的性質
同一類的對象之間可以相互賦值
Point a(2, 3); Point b = a;復制代碼
可以使用對象數組
Point arr[3];復制代碼
可以使用指向對象的指針, 使用取地址運算符&將一個對象的地址賦值給該指針
Point p = &a;p -> display();復制代碼
對象作為函數參數時, 可以使用對象, 對象引用和對象指針三種方式, 推薦使用對象的引用作為函數參數, 可以使用const修飾符保證原來的對象不被修改

一個對象可以作為另一個類的成員

類的性質
使用類的權限
類本身的成員函數可以使用類的所有成員(私有和公有和受保護的成員)
類的對象只能訪問公有成員函數
其它函數不能使用類的私有成員, 也不能使用公有成員函數
雖然一個類可以包含另一個類的對象, 但這個類也只能通過被包含的類對象使用成員函數, 再訪問數據成員
不完全類的聲明
class People; // 不完全的類聲明
People * p; // 定義一個全局變量類指針
只有使用類產生對象時, 才進行內存分配
不完全類不能進行實例化, 否則編譯出錯, 我們使用得不是很多
空類
class Empty {};
可以不包括任何聲明, 也可以沒有任何行為, 但可以產生空類對象
像這樣:

作用: 在開發(fā)大型項目時, 需要在一些類還沒有完全定義或實現(xiàn)時進行先期測試, 保證代碼能正確地被編譯, 當然我們有時也會給它一個無參構造函數, 來消除警告
類的作用域
聲明類時使用的一對花括號{}形成類的作用域, 也包括類體外成員函數的作用域.
在類作用域中聲明的標識符只在類中可見.
像這樣:

總結
每個語言的類和對象其實大同小異, 可能一些名字不一樣, 可能一些格式不一樣, 但是思想是一樣的, 例如一個對象的產生, 都得申請內存, 然后再對這塊內存進行初始化, 有自己的屬性, 還有自己的行為. 我們在學習的時候不要糾結于語言的本身, 要學會總結和自己已經學過的其它語言的異同點, 從而總結出規(guī)律, 提煉出本質, 這才是最主要的. 今天看到一段話送給大家, 大概是這么說的: 不是我們變老了就當不了程序員了, 而是因為我們不想學習了, 所以才顯得我們變老了, 所以也就當不了程序員了!
自學C/C++編程難度很大,不妨和一些志同道合的小伙伴一起學習成長!

另外,UP在主頁上傳了一些學習C/C++編程的視頻教程,有興趣或者正在學習的小伙伴一定要去看一看哦!會對你有幫助的~