C++ (4)面向对象核心:从类与对象到 this 指针,兼谈 Stack 的 C/C++ 实现对比

发布时间:2026/8/27 8:44:10
C++ (4)面向对象核心:从类与对象到 this 指针,兼谈 Stack 的 C/C++ 实现对比 前言C 在 C 语言的基础上引入了面向对象编程OOP范式将数据与操作数据的方法封装在一起极大提升了代码的复用性、可维护性和抽象能力。本文将从最基础的类的定义出发讲解对象实例化与this 指针的核心原理并通过栈Stack数据结构的 C 语言与 C 两种实现对比直观感受面向过程与面向对象的差异。一、类的定义类Class是 C 面向对象的基础它是对一类事物的抽象描述定义了该类事物共同的属性成员变量和行为成员函数。1.1 基本语法1.2 访问控制符C 提供三种访问权限实现了封装特性public公开的类内外均可访问private私有的仅类内部成员函数可访问class 默认权限protected受保护的类内部和派生类可访问1.3 完整示例定义一个栈类封装的核心思想隐藏内部实现细节只对外暴露必要的接口。外部使用者无需知道栈内部用数组还是链表实现只需调用push、pop等函数即可。二、实例化从类到对象类只是一个 “蓝图” 或 “模板”不占用实际内存空间对象是类的具体实例占据真实的内存空间拥有自己的成员变量副本。由类创建对象的过程称为实例化。2.1 两种实例化方式方式一栈上创建对象局部对象方式二堆上创建对象动态分配2.2 内存布局同一个类的多个对象成员变量各自独立但成员函数共享同一份代码。这样设计避免了每个对象都重复存储函数代码节省了内存。内存布局示意图 ┌─────────────────────────────────────────────────────────────┐ │ 代码区共享 │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ Stack::push / Stack::pop 等成员函数 │ │ │ │ 所有对象共享同一份函数代码 │ │ │ └───────────────────────────────────────────────────────┘ │ │ │ │ 对象 s1栈上 对象 s2栈上 │ │ ┌─────────────────────┐ ┌─────────────────────┐ │ │ │ data[0] │ │ data[0] │ │ │ │ data[1] │ │ data[1] │ │ │ │ data[2] │ │ data[2] │ │ │ │ ... │ │ ... │ │ │ │ data[MAX-1] │ │ data[MAX-1] │ │ │ │ top 2 │ │ top 0 │ │ │ └─────────────────────┘ └─────────────────────┘ │ │ ↑ 各自独立的 data 数组和 top 变量 │ └─────────────────────────────────────────────────────────────┘如上图所示s1 和 s2 各自拥有独立的 data 数组和 top 变量互不干扰而 push、pop 等成员函数只保存一份代码所有对象共享调用。当 s1.push() 执行时编译器会隐式传入 s1 的地址this 指针从而操作 s1 自己的 data 和 top。三、this 指针3.1 为什么需要 this 指针既然所有对象共享同一份成员函数代码那么当push函数执行时它怎么知道操作的是哪个对象的data数组和top变量答案就是this 指针。3.2 本质• this 指针是成员函数的一个隐含参数指向当前调用该函数的对象的地址• 它由编译器自动传递我们写代码时不需要显式写出• 在成员函数内部所有对成员变量的访问本质上都是通过3.3 显式使用 this虽然编译器会自动添加但我们也可以显式写出this3.4 关键特点1. this 指针是常量指针不能修改它的指向2. 静态成员函数没有 this 指针因为静态函数不属于某个具体对象3. this 指针存储在栈上作为函数的隐含参数传递四、C 语言 vs C 实现 Stack 对比为了更直观地理解面向对象的优势我们分别用 C 语言和 C 实现一个整数栈从多个维度进行对比。4.1 C 语言实现面向过程C 语言没有类通常用结构体存储数据用独立的函数操作结构体。4.2 C 实现面向对象4.3 全方位对比对比维度C 语言实现C 实现封装性结构体成员全部公开外部可随意修改top和data不安全通过private隐藏内部数据只能通过公有接口访问安全性高代码组织数据结构和操作函数分离命名需加前缀如stackPush避免冲突数据和方法封装在类中天然属于同一命名空间初始化 / 销毁需要手动调用init和destroy容易遗漏导致内存泄漏构造函数和析构函数自动调用对象生命周期管理更可靠函数调用每次都要手动传入结构体指针stackPush(s, val)隐式传递 this 指针写法更简洁s.push(val)扩展性新增功能需要新增独立函数容易造成全局命名污染在类内新增方法即可不影响外部命名空间多态与继承不支持支持继承和多态可轻松扩展出不同类型的栈4.4 核心差异总结C 语言实现的本质是你拿着数据去调用函数处理它 C 实现的本质是你告诉对象去做某件事对象自己内部完成。面向对象不仅仅是语法上的便利更重要的是提供了封装、继承、多态三大特性让我们能够以更贴近人类思维的方式去组织复杂程序。五、总结类是对象的模板封装了数据和方法通过访问控制符实现信息隐藏实例化是由类创建对象的过程对象拥有独立的成员变量共享成员函数this 指针是成员函数的隐含参数指向当前对象解决了函数共享与数据独立的矛盾C 语言基于过程数据与操作分离C 基于对象数据与操作封装更适合构建大型复杂系统理解了类、对象和 this 指针就掌握了 C 面向对象的基石。在此基础上进一步学习构造函数、析构函数、继承和多态就能真正发挥 C 的强大威力。