歡迎來到我的Blog,點擊關注哦💕
前言
前面講到了C++的入門需要學習的知識,是為了后面更好的學習。學習是不斷深入的,內容是不斷復雜的。篤定信心。
一、面向對象編程(OOP)和面向過程編程(POP)的認識
面向過程編程(Procedural Programming,簡稱POP)
POP特性
- 程序的核心是函數,這些函數是一系列預定義操作的集合,旨在執行特定任務。
- 這種方法讓程序員可以重用代碼,提高效率,并且使代碼更易于跟蹤和維護。
- 通過將復雜問題拆解為更小、更具體的任務,面向過程編程使解決問題變得更加直接.
面前對象編程(Object Oriented Programming,簡稱OOP)
OOP特性
- 封裝:是將對象的屬性和方法結合在一起,并盡可能隱藏對象的內部細節,只暴露必要的接口供外部使用。
- 繼承:允許一個類(子類)繼承另一個類(父類)的屬性和方法,實現代碼的重用和層次化組織。
- 多態:允許使用相同的接口來處理不同類型的對象,具有不同的實現,增加了代碼的靈活性和可擴展性.
二、類
類的定義:類是用戶自定義的數據類型,它允許將數據(成員變量)和操作數據的函數(成員函數)封裝在一起。
類的定義
class ClassName {
public:// 公共成員聲明
private:// 私有成員聲明
protected:// 受保護成員聲明
};
訪問限定修飾符
- public(公有):公有成員可以在類的內部、派生類和類的外部訪問。它們構成了類的公共接口,通常用于定義可以被外部直接訪問和操作的方法和屬性。
- protected(受保護):受保護的成員只能在類的內部和派生類中訪問,而不能在類的外部訪問。它們用于實現基類和派生類之間的共享實現細節。
- private(私有):私有成員只能在類的內部訪問,外部無法直接訪問。私有成員用于隱藏類的內部實現細節,防止外部代碼直接訪問和修改類的狀態
類和結構區別
在C++ 中將 C語言中 struct升級成了類,在C++中strcut也可以聲明類。
- 結構(struct)默認訪問類型是 public
- 類的默認訪問類型是private
類的作用域
**類 **: 類的作用域是指類定義中聲明的成員變量和成員函數的可見范圍。類的作用域由類名和作用域解析運算符(::)共同控制。
類的實例化
類的實例化:指創建類的具體對象的過程。這個過程通常涉及到分配內存空間給新創建的對象,并設置其初始屬性值。
例如:
class Stack
{//類定義
};int main()
{Stack st;return 0;
}
對象的大小
對象的大小類似于C語言中的結構體大小的計算方法。
- 第一個成員在與結構體偏移量為0的地址處。
- 其他成員變量要對齊到某個數字(對齊數)的整數倍的地址處。 注意:對齊數 = 編譯器默認的一個對齊數 與 該成員大小的較小值。 VS中默認的對齊數為8
- 結構體總大小為:最大對齊數(所有變量類型最大者與默認對齊參數取最小)的整數倍。
- 如果嵌套了結構體的情況,嵌套的結構體對齊到自己的最大對齊數的整數倍處,結構體的整 體大小就是所有最大對齊數(含嵌套結構體的對齊數)的整數倍
class A1 {
public:void f1(){}
private:int _a;
};
// 類中僅有成員函數
class A2 {
public:void f2() {}
};
// 類中什么都沒有---空類
class A3
{};
- sizeof(A1) = 4
- sizeof(A2) = 1
- sizeof(A3) = 1
C++標準規定空類必須具有非零大小的原因主要有以下幾點
-
確保對象地址唯一性:C++標準要求不同的對象不能具有相同的地址。如果空類的大小為0,那么在數組中連續創建多個空類對象時,這些對象將沒有區分它們的內存空間,從而違反了這一原則.
-
避免指針運算問題:如果空類的大小為0,那么使用指針進行算術運算時將無法正確計算偏移量,因為除以0是非法的操作。這將導致編譯器需要編寫額外的代碼來處理這些異常情況.
-
內存分配和對齊:新對象的分配需要不同的內存地址,且內存分配通常考慮到對齊要求。一個非零大小的空類可以確保即使是最基本的對象也至少占據一個內存單元,滿足基本的內存對齊要求.
-
優化空間利用:C++標準允許空基類優化,即如果空類作為基類時不會與同一類型的另一個對象或子對象分配在同一地址,編譯器可以選擇不為其分配任何空間。這意味著空類的非零大小實際上不會增加派生類的內存占用,除非派生類本身需要更多空間.
三、this指針
this
指針是一個隱含的成員指針,它在類的非靜態成員函數中可用,指向調用該函數的對象實例。
this
指針是一個常量指針,其指向的內容可以被修改,但指針本身不能被重新賦值。this
指針的類型是指向類類型的指針,即const ClassType*
。this
指針在成員函數的整個執行期間都存在,其生命周期與函數的其他參數相同。this
指針不是對象內存的一部分,因此不會影響對象的大小
class A
{
public:void Print(){cout << "Print()" << endl;}
private:int _a;
};
int main()
{A* p = nullptr;p->Print();return 0;
}
class B
{
public:void PrintB() {cout<<_a<<endl;}
private:int _a;
};
int main()
{B* p = nullptr;p->PrintB();return 0;
}
- A會正常運行, 因為p調用的公共代碼塊的,沒有進行成員訪問。
- B段代碼進行了成員訪問,Print函數內部 this->_a。