C++面對物件(一)
-
程式設計方法:
- 結構化程式設計
- 面向物件的程式設計
- 類
- 物件
-
類
- 變數:描述物件屬性(資料成員)
- 函式:描述物件行為(成員還是)
-
定義類
有三種訪問控制方式:
class 類名 { public: 公有成員:任何地方都可以訪問 private: 私有成員:該類 成員函式 protected: 保護成員:該類 + 派生類 成員函式 友元函式(特殊):隨便訪問 }
注意:
- 不寫訪問控制方式,預設private
- 類的友元可以訪問類及其派生類的任何東西
-
建構函式
形式區別:
// 建構函式 <類名> (形參表){ 函式體 } // 一般函式 <返回型別> <函式名>(形參表{ 函式體 }
引數:
- 有參
- 無參
返回值:
- 無值 void (可以沒有return,或者return;)
- 有值
建構函式特殊:
-
建構函式沒有任何返回型別,不可以寫 void
-
函式名就是類名(判斷一個函式是否為建構函式的依據)
-
可以過載(有參/無參)
函式過載:C++中不同的函式有相同的函式名。以傳入實參的數量/型別來決定呼叫哪個函式。
-
類定義中,若未寫建構函式,系統提供一個無函式體的無參建構函式
-
作用:
- 為物件分配記憶體空間
- 完成對該物件資料成員的初始化操作
-
如果在建立新物件的時候,建構函式由系統自動呼叫。
若一個物件已經被建立,再進行顯示呼叫的時候,就會報錯。
// 初始化自動呼叫有參的 Circle circleC(3.5, 4.5, 45.6); // 再次顯示呼叫,報錯 corcleC.circle(3.5, 4.5, 45.6);
呼叫類物件方法:
物件.方法 指標->方法
-
解構函式
// 解構函式不可以有形參 virtual ~<類名> (){ 函式體,銷燬物件 }
特點:
- 沒有任何返回型別
- 函式名就是類名
- 只可以無參(一定不可過載)
- 類定義中未定義解構函式,系統提供一個沒有函式體的解構函式。
- 最好+\(virtual\)
作用:
- 在物件生存週期結束後,“善後工作”(比如我們new出來的記憶體,要進行刪除)
-
拷貝建構函式
作用:用一個已存在物件來初始化一個正在建立的新物件
特點:
-
函式名也是類名
-
形參只有一個,是物件的引用
-
也是建構函式,所以沒有返回型別
-
函式原型
<類名>(<類名> &物件名)
函式原型:形參表中給出形參個數、型別,不用給具體名稱。
為什麼引數是這樣的:類 物件 關係 ==> 資料型別 變數 關係:
Circle (Circle &circle)
拷貝型別:
- 淺拷貝(預設、系統自帶)
- 深拷貝(使用者自定義)
// 呼叫有參構造 IntArray x(20); // 呼叫拷貝構造(用x去初始化y) IntArray y(x);
淺拷貝:指向同一塊記憶體區域,析構2次
-
-
類宣告和實現分離(函式定義與函式宣告)
-
類宣告(放在標頭檔案 .h 中)
用途:描述類的結構
- 類的資料成員
- 有哪些成員函式
- 友元函式
-
類實現(放在原始檔 .cpp 中)
用途:描述成員函式具體的功能
注意:
-
.cpp中寫出
#include “*.h”
”"
先在當前資料夾搜尋,再到系統預設資料夾搜尋<>
直接在系統預設資料夾搜尋
-
類實現中成員函式形式:
// 普通函式 <返回型別> <函式名>(形參表){ 函式體 } // 成員函式 <返回型別> <類名>::<函式名>(形參表){ 函式體 }
- 增加
<類名>::
,指出所定義的成員函式屬於哪個類 (::作用域運算子)
- 增加
為啥要分離?
- 保密
- 加快編譯(連結)
-
-
類的靜態資料成員
特點:
- 類內宣告(.h)、類外初始化(.cpp)
- 該變數所有由該類派生的物件共享(修改同步)
// .h static int x;
// .cpp // 靜態 <型別> <類名>:: <變數> = <初值> ;
只要是類宣告和實現的分離,就一定要寫清楚,這個變數、函式屬於誰。
- 靜態成員變數要在類定義中宣告,在類外進行初始化(前者說明,它還是屬於這個類的,後者是因為這個變數要存在全域性變數區,C++還是面向機器的語言)
- 類外初始化不用static
-
類的常量成員
-
資料成員,語法:
const int x;
注意:
- 常量資料成員在宣告時候不可被賦初值,在定義物件時,利用建構函式賦初值,有值後就不可修改。
- 普通資料成員,也最好在建構函式裡。
-
成員函式,語法:
<型別> <函式名> (形參表) const
,只可讀,不可寫
-
-
this 指標(非靜態成員函式)
-
隱式呼叫:,預設會隱式呼叫this指標
-
顯示呼叫:
-
形參名,與類的資料成員名相同
Point (float x, float y){ this->x = x; // x = x??? this->y = y; // 等價於 Point.x = x; }
-
返回值,物件本身,或者這個物件的地址(this ~ &物件名)
- 物件地址:
return this
- 物件本身(取地址值):
return *this
- 物件地址:
-
-
-
友元
為什麼要出現友元?
一個類中的函式,一般無法直接訪問另一個類中私有/保護成員,我們用友元函式來做。好處:提高了程式的效率,壞處:破壞了封裝性
友元:
-
友元函式:將某個函式宣告為友元函式,該函式,可以訪問同一個類中任何成員
定義:
friend <函式型別> <函式名>(<形參表>);
-
友元成員:將一個類中成員函式A,宣告為另一個類B的友元函式
用途:在A類中的一個函式,可以訪問B中任一成員變數(B說,A是我的朋友,A可以訪問B類的任何東西)
定義(兩步法):
-
在 A 類中宣告成員函式
class A { int func (int x); }
-
在 B 類中宣告 A 類的成員函式,作為B類的友元(B的資源可以任意訪問)
class B { // A::** 將 A 類中的func放進來 friend int A:: func(int x); }
-
-
友類:A類中所有成員函式,均可訪問B類中所有成員。
定義(兩步法):
-
先定義A 類
class A { }
-
在B類中宣告A是B的友類:
class B{ // 把A類作為B的朋友(朋友) freind class A; }
注意:
- 單向性:A是B的友類,B不是A的友類。
- 非傳遞性:A是B的友類,B是C的友類,A不是C的友類
-
-
思維導圖: