一、面向對象和面向過程
1、什么是面向過程(Process-Oriented Programming, POP)
📌 定義
面向過程強調的是?過程(過程=函數),即:按照步驟(流程)組織代碼。
程序結構 = 數據結構 + 操作這些數據的函數。
程序的主要設計思想是:先干什么,再干什么,順序執行,遇事用函數搞定。
📌 特點
數據與函數分離
強調模塊化、函數復用
程序結構清晰,適合小項目或底層開發
缺乏對復雜數據結構的抽象能力
C 語言是典型的面向過程語言:關注過程,分析求解問題的步驟,通過函數調用逐步解決問題。
struct Student {char name[20];int age; };void printStudent(struct Student s) {printf("%s %d\n", s.name, s.age); }int main() {struct Student s = {"Tom", 20};printStudent(s); // 操作結構體由外部函數處理 }
2、什么是面向對象(Object-Oriented Programming, OOP)?
📌 定義
面向對象強調的是“對象(object)”:
把數據和操作這些數據的方法封裝成一個整體(類),對象是類的實例。
📌 核心特性(C++ 支持)
特性 | 含義 |
---|---|
封裝 | 數據和函數封裝在類中,提高安全性與模塊化 |
繼承 | 子類自動繼承父類成員,提高復用性 |
多態 | 同一個接口有不同表現形式(如虛函數) |
?C++ 是支持面向對象的語言:關注的是對象,將一件事情拆分成不同的對象,靠對象之間的交互完成
class Student { public:string name;int age;void print() {cout << name << " " << age << endl;} };int main() {Student s;s.name = "Tom";s.age = 20;s.print(); // 數據和方法封裝在類內部 }
3、兩種范式對比總結
比點 | 面向過程(C) | 面向對象(C++) |
---|---|---|
編程核心 | 函數、流程 | 對象、類 |
數據與函數 | 分離 | 封裝在一起 |
適用場景 | 小型、過程性、底層開發 | 中大型、復雜、維護性強項目 |
可擴展性 | 差 | 強 |
典型語言 | C | C++、Java、Python(OOP) |
面向過程強調“做什么”,面向對象強調“誰來做”;
C 是“寫過程”的語言,C++ 是“建模型”的語言。
二、c++類的引入
????????c語言中,結構體只能定義變量,在c++中,結構體內不僅可以定義變量,也可以定義函數。
1、類的基本語法和使用
直接定義:
//類里面可以定義:1成員變量,2成員方法(函數)class Person { public: //訪問限定符--公有void showInfo(){cout<< _name<<"-"<<_sex<<"-"<<_age<<"-"<<endl;}public: // 訪問權限char* _name; // 成員變量char* _sex;int _age; };
分開定義,在頭文件中聲明,cpp中定義
頭文件中的聲明:
class Person { public://訪問限定符--公有//顯示基本信息void showInfo();public: // 訪問權限char* _name; // 成員變量int _age;char* _sex;};
cpp文件的定義
#include "class.h"void Person::showInfo(){cout<< _name<<"-"<<_sex<<"-"<<_age<<"-"<<endl; }
c++類的訪問限定符
關鍵字 | 說明 |
---|---|
public | 類外可訪問 |
private | 類外不可訪問,僅類內和友元函數可訪問 |
protected | 類外不可訪問,派生類可訪問 |
默認訪問權限:class?默認是?private,struct?默認是?public。struct也可以定義類。
利用類實現數據結構中的棧等
//利用類實現數據結構中的棧。 class Stack{public:void STInit(){//..../}void STpush(int x){//..../}void STpop(){//..../}void PrintST(){//..../}void Destroy(){//..../}private:int Top;int* _arr;int _capacity; };int main(){Stack ST;ST.STInit(10);ST.STpush(1);ST.STpush(10); }
c語言結構體和c++結構體定義的區別:
? ? ? ? c++中,兼容c的struct的定義結構體的方法,但同時struct也可以用來定義類。
????????struct所定義的類 默認是?public, class 定義的類默認是private 。
????????
//c語言用于定義結構體 struct ListNodeC{struct ListNodeC* prev;struct ListNodeC* next; }; //c++定義結構體 struct ListNodeCPP{//同時也可以定義類ListNodeCPP* prev;ListNodeCPP* next;//這里仍然可以定義函數->成員函數ListNodeCPP* Creat(); }
c++ 兼容 c語言的用法。
類的內存占用
class Stack{//1、成員函數 public:void Push(int x); //函數的聲明void Pop(); //函數可以在類中定義,也可以在類外定義。 bool IsEmpty();//2、成員變量 public:int* _arr;int _size;size_t _capactity;};int main(){//類實例化出對象,相當于定義出類的成員變量Stack s1;Stack s2;Stack s3;// s1.Push(1);cout << sizeof(s1) << endl;//計算內存占用大小return 0; }
輸出如下:
24 --> macos arm64架構下,int* 占用8個字節
根據內存對齊:
int*?要求 8 字節對齊
int?要求 4 字節對齊
所以整體對齊到 8 的倍數
共24字節。那也就是成員函數不占字節。
原因:一個類可以實例化n個對象,每個成員變量都可以存儲不同的值,但是調用的函數確是同一個。所以成員函數不占類對象的內存,成員函數是?代碼段(.text 段),與對象無關。
????????所以:sizeof(類對象)?只與?成員變量?有關,與成員函數無關
當我們的類中,成員變量為空,成員函數為空的情況下,內存大小是多少呢?
class A2{public:void f1(); };class A3{};int main(){cout << sizeof(A2) << endl;cout << sizeof(A3) << endl;return 0; }
輸出結果:
1
1
1?? C++標準規定:
每個對象必須有唯一地址
如果類的大小是?0,那多個對象就可能共享同一塊地址(比如全都指向空地址?0x1234)
為了保證對象在內存中“可區分”,編譯器會強制空類占用至少 1 字節
2?? 類中只有函數時,仍然認為“沒有數據成員”
成員函數是**代碼段(text segment)**的一部分,不存儲在對象中
所以?A2?仍然是空類(empty class),編譯器仍然會分配?1 字節
類的實例化 --> 就是用自己定義的類型定義出對象
1、內置類型,基本類型 int/char/double
2、自定義類型,class/struct。
面向對象的三大特性:封裝,繼承,多態。