一、面向对象和面向过程
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。
面向对象的三大特性:封装,继承,多态。