当前位置: 首页 > news >正文

《C++初阶之类和对象》【类 + 类域 + 访问限定符 + 对象的大小 + this指针】

什么是类?

类(Class):是对具有相同属性(数据)方法(行为)的一组对象的抽象描述

  • 类是 C++ 的核心特性之一,用于实现面向对象编程(OOP)中的封装
  • 类是对象的蓝图,定义了对象的属性(数据成员)行为(成员函数)

一个形象的例子:比如 “人类”,可以有姓名、年龄等属性,以及说话、行走等行为,在编程里就可据此定义一个 “人类” 的类。

怎么定义类?

代码语言:javascript

AI代码解释

class Person { public: void setAge(int a) { age = a; } int getAge() { return age; } private: };

C++使用class关键字定义,类中包含以下三部分的内容。类的基本结构:关键的三个组成部分

  • 数据成员(属性):类的变量(int age;
  • 成员函数(方法):类的函数(void setAge(int a) 和 int getAge()
  • 访问修饰符
    • public:任何地方可访问
    • protected:类及其子类可访问
    • private:仅类内部访问(默认)
关于类需要注意什么?

下面博主挑选了四个关于“类”需要注意的事项,它们分别是关于:

  1. 类定义的语法规范
  2. 成员变量的命名约定
  3. structclass的区别
  4. 类内定义的成员函数与内联

1. 类定义的语法规范

分号结尾:类定义结束时必须使用分号;,这是 C++ 语法的强制要求。

代码语言:javascript

AI代码解释

class MyClass // 类定义开始 { // 成员... }; // 分号不可省略!

2. 成员变量的命名约定

命名前缀 / 后缀:为避免成员变量与局部变量或函数参数重名,通常添加特殊标识:

代码语言:javascript

AI代码解释

class Person { private: int m_age; // m_前缀(Microsoft风格) std::string _name; // 前缀(常见于开源项目) double salary_; // 后缀(Google风格) };

注意:C++ 标准并未强制要求此规则,具体风格需遵循团队或项目规范。

3.structclass的区别

特性

struct

class

默认访问权限

public

private

设计哲学

数据聚合(POD, Plain Old Data)

封装复杂逻辑(OOP)

常见用途

轻量级数据容器、C 兼容结构

封装、继承、多态

示例对比

代码语言:javascript

AI代码解释

struct Point { int x, y; // 默认public void move(int dx, int dy); //注意:可定义函数 }; class Rectangle { int width, height; // 默认private public: int area() const { return width * height; } };

4. 类内定义的成员函数与内联

隐式内联:在类内部直接定义的成员函数会被编译器视为inline函数(但最终是否内联由编译器决定)

代码语言:javascript

AI代码解释

class Math { public: int add(int a, int b) // 隐式内联 { return a + b; } };

显式内联:若在类外定义函数,需显式使用inline关键字(通常在头文件中):

代码语言:javascript

AI代码解释

// Math.h class Math { public: int multiply(int a, int b); // 声明 }; // Math.cpp inline int Math::multiply(int a, int b) // 显式内联 { return a * b; }

注意事项

  • 内联函数的定义必须在每个调用它的翻译单元(.cpp 文件)中可见,因此通常直接放在头文件中。
  • 现代编译器会智能优化内联决策,即使未声明inline,简单函数也可能被自动内联。
C++中的struct关键字有什么变化?

刚才我们有提到使用关键字struct来定义类,相比C++中的struct和C语言中的struct已经不太一样了吧,那两者又有什么区别呢?

代码语言:javascript

AI代码解释

include<iostream> using namespace std; /* * C++ 中对 struct 的升级: * 1. struct 现在是一个完全的类(class),内部可以定义成员函数 * 2. struct 名称本身可以直接作为类型名使用(不再需要 typedef) */ // ------------------------- C 语言风格的链表节点 ------------------------- // C 中需要 typedef 简化类型名称 typedef struct SingleListNodeC { int val; struct ListNodeC* next; // C 中必须带 struct 关键字 }SLTNode; // 通过 typedef 定义类型别名 LTNode // ------------------------- C++ 风格的链表节点 ------------------------- // C++ 中 struct 本身就是类型名,且支持成员函数 struct SingleListNodeCPP { // 成员函数:初始化节点 void Init(int x) { val = x; // 设置节点值 next = nullptr; // 初始化指针为空 } // 成员变量 int val; SingleListNodeCPP* next; // 直接使用 SingleListNodeCPP 作为类型(无需 struct 关键字) }; /* * 对比说明: * 1. C++ 的 struct 默认所有成员为 public(与 class 的唯一区别) * 2. 完全支持构造函数、析构函数等类特性 * 3. 兼容 C 的语法,但更推荐 C++ 风格 */ int main() { // C 风格用法(兼容模式) SLTNode node_c; node_c.val = 10; node_c.next = NULL; // C++ 风格用法 SingleListNodeCPP node_cpp; node_cpp.Init(20); // 调用成员函数初始化 return 0; }

对比维度

C 语言风格 struct

C++ 风格 struct

类型定义方式

需用typedef定义类型别名简化使用,定义时节点类型前需加struct关键字

struct名称本身就是类型名,可直接使用,无需typedef和额外的struct关键字

成员函数支持

仅能定义数据成员,不支持成员函数

可定义成员函数,如案例中SingleListNodeCPP的Init函数用于初始化节点

访问权限默认值

无明确访问权限概念(类似 C++ 中public ,所有成员都可直接访问 )

默认成员访问权限为public(与class不同,class默认private )

使用类有哪些好处?

接下来我们就使用C++的类再次重新实现一下我们在《数据结构初阶》中实现的栈这种数据结构,直观的感受一下使用类实现和之前实现的区别:

代码语言:javascript

AI代码解释

#include<iostream> #include<cstdlib> #include<cassert> using namespace std; // 定义一个栈(Stack)类,基于动态数组实现 class Stack { public: /*-------------------------栈的“初始化”操作-------------------------*/ /* * 初始化栈,默认初始容量为4 * 参数n:可选参数,指定初始容量,默认为4 */ void Init(int n = 4) { //申请n个int大小的内存空间 array = (int*)malloc(n * sizeof(int)); // 检查内存是否申请成功 if (array==nullptr) { perror("malloc申请空间失败"); return; } // 初始化栈的容量和栈顶指针 capacity = n; top = 0; //top指向下一个可插入的位置 } /*-------------------------栈的“入栈”操作-------------------------*/ void Push(int x) { // 这里应该添加扩容逻辑,当top == capacity时需要扩容 // 当前实现没有扩容功能,会导致数组越界 // array[top++] = x; // 元素放入数组,然后top指针后移 } /*-------------------------栈的“获取栈顶元素”操作-------------------------*/ int Top() { assert(top > 0); //断言检查栈是否为空 return array[top - 1]; } /*-------------------------栈的“销毁”操作-------------------------*/ void Destroy() { free(array); // 释放动态数组 array = nullptr; // 指针置空,防止野指针 top = capacity = 0; // 重置容量和栈顶指针 } private: /*---------------------成员变量---------------------*/ int* array; // 动态数组指针,存储栈元素 int capacity; // 栈的容量 int top; // 栈顶指针(指向下一个可插入位置) }; int main() { Stack st; // 创建栈对象 st.Init(); // 初始化栈(使用默认容量4) st.Push(1); // 压入元素1 st.Push(2); // 压入元素2 // 输出栈顶元素(应该是2) cout << st.Top() << endl; st.Destroy(); // 销毁栈,释放资源 return 0; }

这里我们最能明显体会到的区别有以下三点:

维度

C语言实现

C++类实现

数据与操作

分离(结构体+独立函数)

整合(成员变量+成员方法)

实例表示

显式传递结构体指针(Stack*)

隐含this指针(st.Push())

访问控制

无封装(所有字段可被外部直接修改)

通过private保护关键数据

---------------类的实例化---------------

什么是类的实例化?

类的实例化:是指根据类的定义创建具体对象的过程。

  • 实例化后,对象会获得类中定义的成员变量(数据)和成员函数(行为),并占用实际的内存空间。

实例化的核心概念

  • 类(Class):是对象的蓝图或模板,仅定义结构,不占用内存。
  • 对象(Object):是类的具体实例,占用内存,存储实际数据。

类比

  • 类 ≈ 建筑设计图
  • 对象 ≈ 按设计图建造的房子

在面向对象编程中,一个类可以实例化出多个对象,这些实例化出的对象会占用实际的物理空间,用于存储类成员变量。 类与对象的关系就好比建筑设计图与实际建筑:建筑设计图详细规划了房屋的结构,如房间数量、空间布局、功能分区等,但它只是概念性的图纸,并不具备实体形态,无法供人居住或使用;只有依照设计图施工建造出实际的房屋,才能满足居住、办公等实际需求。 同理,类是对数据和行为的抽象描述,定义了成员变量和成员函数,但它本身并不占据物理内存,也无法存储实际数据,仅作为对象创建的模板。 而通过类实例化得到的对象,就像建造完成的房屋,会在计算机内存中分配实际的空间,用于存储类所定义的成员变量的值。

  • 例如:通过 “学生” 类可以实例化出张三、李四等具体学生对象,每个对象都有自己独立的存储空间,用于存放各自的姓名、年龄、成绩等成员变量数据,且不同对象的同一成员变量可以存储不同的值。
  • 多个对象之间相互独立,各自存储和管理自己的数据,却又共享类所定义的行为和操作规范,使得程序能够高效地处理复杂的现实场景。
http://www.jsqmd.com/news/474841/

相关文章:

  • 计立伟时空归一化理论体系:从螺旋几何到大一统场方程
  • QtPy(PySide6),在线程中使用QEventLoop实现低成本待机
  • Phi-3-mini-128k-instruct实操手册:vLLM推理引擎配置参数详解与最佳实践
  • XGigE IP GigE Vision Streaming Protocol VHDL源码 ...
  • 基于VRRP的IR615路由器双机热备份配置实践
  • 扶摇速记之S:你觉着它像什么,它就是什么
  • SecGPT-14B效果展示:对未标注原始日志进行攻击类型分类(WebShell/Brute/Scan)
  • 基于PLC的污水处理系统设计:S7 - 200与MCGS的完美搭档
  • 【论文阅读】VideoWorld 2: Learning Transferable Knowledge from Real-world Videos
  • C++初阶之类和对象》【初始化列表 + 自定义类型转换 + static成员】
  • 2026年热门上线即送神装的传奇网页游戏精选
  • 基于S7 - 200 PLC和组态王小区变频恒压供水控制系统设计
  • 2026工业废气治理设备厂家+中水回用水处理系统厂家+一体化污水处理设备厂家-石家庄天旺环保科技领衔 - 栗子测评
  • Claude 5天重写老库引全网争议,维护者擅自更换开源协议,退网15年原作者突然现身:不准改!
  • 《C++初阶之类和对象》【友元 + 内部类 + 匿名对象】
  • 当变频器遇上S7-200:一个水厂老司机的自白
  • 基于CW32F030C8T6的BMP180气压传感器I2C驱动移植与海拔测量实战
  • 《C++初阶之STL》【auto关键字 + 范围for循环 + 迭代器】
  • 2026年混凝土外加剂实力厂家甄选指南与TOP5推荐 - 2026年企业推荐榜
  • 八皇后(dfs 模版
  • YOLOv5+GraspNet实战:如何用Python快速搭建机械臂抓取系统(附完整代码)
  • ESP32S3基础2-多任务处理、EXTI中断、时钟与定时器
  • MySQL【表的约束下】
  • 手把手教你用阿里云镜像制作glibc.i686离线安装包(CentOS7专属)
  • [特殊字符] Nano-Banana实战案例:从手机到家电,全品类产品拆解图生成实录
  • Zotero7文献笔记模版:从安装到自定义的完整指南
  • 喜讯!第十六批生成合成类算法备案备案号公布
  • 天梯赛编程题 L2—048 寻宝图 题解
  • 软件安全实战指南:从零日漏洞到安全部署的核心要义
  • Visual Studio误删.vcxproj.filters文件?3步教你手动重建(附模板)