C++ 类与对象:封装特性的实现与实战应用

C++ 类与对象:封装特性的实现与实战应用

C++ 类与对象:封装特性的实现与实战应用

在这里插入图片描述

💡 学习目标:掌握类与对象的核心概念,理解封装的本质与价值,能够独立设计并实现具有封装特性的 C++ 类。
💡 学习重点:类的定义与对象实例化、访问权限控制、构造函数与析构函数的使用、封装的实战场景应用。

一、类与对象的核心概念

结论:类是 C++ 面向对象编程的核心载体,是对一类事物属性和行为的抽象描述;对象是类的具体实例,是内存中实际存在的实体。

1.1 类的组成

一个完整的 C++ 类通常包含两部分:

  • 成员变量:描述类的属性,如人的姓名、年龄,圆的半径等。
  • 成员函数:描述类的行为,如人的吃饭、跑步,圆的面积计算等。

1.2 类的定义格式

#include<iostream>#include<string>usingnamespace std;// 类的定义:以 class 关键字开头classPerson{// 访问权限修饰符,后续详细讲解private:// 成员变量:属性 string name;int age;public:// 成员函数:行为voidsetInfo(string n,int a);// 设置属性voidshowInfo();// 展示属性};

1.3 对象的实例化与使用

对象是类的具体实例,实例化对象的语法与定义普通变量类似,有两种常见方式:

// 方式1:栈上实例化对象 Person p1; p1.setInfo("张三",20); p1.showInfo();// 方式2:堆上实例化对象(需要用 new 关键字) Person *p2 =newPerson(); p2->setInfo("李四",25); p2->showInfo();// 堆上对象使用后需手动释放内存delete p2; p2 =nullptr;

二、封装的本质:访问权限控制

💡 封装是面向对象三大特性之一,核心是通过访问权限修饰符隐藏类的内部实现细节,只对外暴露必要的接口,提高代码的安全性和可维护性。

C++ 提供了三种访问权限修饰符,作用域从修饰符出现位置开始,到下一个修饰符或类结束为止。

2.1 三种访问权限

修饰符访问范围核心特点
public类内、类外、子类对外公开的接口,允许外部直接访问
protected类内、子类仅允许类自身和子类访问,类外不可见
private类内仅允许类自身访问,子类和类外均不可见

⚠️ 注意事项:类的默认访问权限是 private,结构体 struct 的默认访问权限是 public

2.2 访问权限的代码演示

#include<iostream>#include<string>usingnamespace std;classPerson{// 默认 private string addr ="北京市";private: string name;int age;public:voidsetInfo(string n,int a){// 类内可以访问 private 成员变量 name = n; age = a;}voidshowInfo(){ cout <<"姓名:"<< name <<" 年龄:"<< age <<" 地址:"<< addr << endl;}};intmain(){ Person p; p.setInfo("王五",30); p.showInfo();// 错误:name 是 private 成员,类外无法访问// p.name = "赵六";// 错误:addr 是默认 private 成员,类外无法访问// p.addr = "上海市";return0;}

三、构造函数与析构函数:对象的生命周期管理

💡 构造函数负责对象的初始化,析构函数负责对象的清理工作,二者均由编译器自动调用,无需手动触发。

3.1 构造函数

3.1.1 构造函数的特性
  • 函数名与类名完全相同,没有返回值类型,连 void 都不能写。
  • 对象实例化时自动调用,且只调用一次。
  • 可以重载,支持不同方式的初始化。
  • 如果没有手动定义构造函数,编译器会自动生成一个空参构造函数
3.1.2 构造函数的分类与实现
#include<iostream>#include<string>usingnamespace std;classPerson{private: string name;int age;public:// 1. 空参构造函数(默认构造函数)Person(){ cout <<"空参构造函数被调用"<< endl; name ="未知"; age =0;}// 2. 有参构造函数Person(string n,int a){ cout <<"有参构造函数被调用"<< endl; name = n; age = a;}// 3. 拷贝构造函数(用已有对象初始化新对象)Person(const Person &p){ cout <<"拷贝构造函数被调用"<< endl; name = p.name; age = p.age;}voidshowInfo(){ cout <<"姓名:"<< name <<" 年龄:"<< age << endl;}};// 构造函数的调用方式intmain(){// 方式1:括号法 Person p1;// 调用空参构造 Person p2("张三",20);// 调用有参构造 Person p3(p2);// 调用拷贝构造// 方式2:显示法 Person p4 =Person(); Person p5 =Person("李四",25);// 方式3:隐式转换法(不推荐) Person p6 ={"王五",30}; p1.showInfo(); p2.showInfo();return0;}

⚠️ 注意事项:使用括号法调用空参构造时,不能写 Person p1(),这会被编译器识别为函数声明,而非对象实例化。

3.2 析构函数

3.2.1 析构函数的特性
  • 函数名以 ~ 开头,后跟类名,没有返回值类型,也没有参数。
  • 对象销毁时自动调用,且只调用一次。
  • 不能重载,一个类只能有一个析构函数。
  • 如果没有手动定义析构函数,编译器会自动生成一个空析构函数。
3.2.2 析构函数的实战价值

析构函数常用于释放对象占用的动态资源,如堆内存、文件句柄等,避免内存泄漏。

#include<iostream>#include<string>usingnamespace std;classStudent{private: string *name;// 堆内存指针int age;public:// 有参构造:分配堆内存Student(string n,int a){ cout <<"有参构造函数被调用"<< endl; name =newstring(n);// 堆上分配字符串 age = a;}// 析构函数:释放堆内存~Student(){ cout <<"析构函数被调用"<< endl;if(name !=nullptr){delete name;// 释放堆内存 name =nullptr;// 防止野指针}}voidshowInfo(){ cout <<"姓名:"<<*name <<" 年龄:"<< age << endl;}};intmain(){// 栈对象:函数结束时自动销毁,触发析构函数 Student s1("小明",18); s1.showInfo();// 堆对象:手动 delete 时触发析构函数 Student *s2 =newStudent("小红",17); s2->showInfo();delete s2; s2 =nullptr;return0;}

四、封装的实战案例:设计一个圆形类

💡 需求:设计一个圆形类 Circle,包含半径属性,提供设置半径、计算面积、计算周长的功能,要求通过封装隐藏半径的直接访问,确保半径的合法性。

4.1 需求分析

  1. 成员变量:半径 radius,设置为 private,避免外部直接修改。
  2. 成员函数:
    • setRadius(double r):设置半径,需校验半径是否大于 0。
    • getRadius():获取半径,对外提供只读接口。
    • getArea():计算圆的面积,公式:S=πr2S = \pi r^2S=πr2。
    • getPerimeter():计算圆的周长,公式:C=2πrC = 2\pi rC=2πr。
  3. 构造函数:提供空参和有参构造,初始化半径。

4.2 完整代码实现

#include<iostream>#include<cmath>usingnamespace std;// 定义圆周率常量constdouble PI =acos(-1.0);classCircle{private:// 私有成员变量:半径double radius;public:// 空参构造:默认半径为 0Circle(){ radius =0.0; cout <<"空参构造函数被调用,默认半径 0"<< endl;}// 有参构造:初始化半径Circle(double r){setRadius(r);// 调用 setRadius 做合法性校验 cout <<"有参构造函数被调用,半径设置为 "<< radius << endl;}// 设置半径:校验合法性voidsetRadius(double r){if(r >=0){ radius = r;}else{ cout <<"⚠️ 半径不能为负数,默认设置为 0"<< endl; radius =0.0;}}// 获取半径doublegetRadius(){return radius;}// 计算面积doublegetArea(){return PI * radius * radius;}// 计算周长doublegetPerimeter(){return2* PI * radius;}};intmain(){// 测试空参构造 Circle c1; cout <<"圆1 半径:"<< c1.getRadius()<< endl; cout <<"圆1 面积:"<< c1.getArea()<< endl; cout <<"圆1 周长:"<< c1.getPerimeter()<< endl; cout <<"-------------------------"<< endl;// 测试有参构造:合法半径 Circle c2(5.0); cout <<"圆2 半径:"<< c2.getRadius()<< endl; cout <<"圆2 面积:"<< c2.getArea()<< endl; cout <<"圆2 周长:"<< c2.getPerimeter()<< endl; cout <<"-------------------------"<< endl;// 测试非法半径设置 Circle c3(-3.0); cout <<"圆3 半径:"<< c3.getRadius()<< endl;// 动态修改半径 c3.setRadius(4.0); cout <<"修改后圆3 半径:"<< c3.getRadius()<< endl; cout <<"修改后圆3 面积:"<< c3.getArea()<< endl;return0;}

4.3 运行结果

空参构造函数被调用,默认半径 0 圆1 半径:0 圆1 面积:0 圆1 周长:0 ------------------------- 有参构造函数被调用,半径设置为 5 圆2 半径:5 圆2 面积:78.5398 圆2 周长:31.4159 ------------------------- ⚠️ 半径不能为负数,默认设置为 0 有参构造函数被调用,半径设置为 0 圆3 半径:0 修改后圆3 半径:4 修改后圆3 面积:50.2655 

五、封装的优势与开发规范

封装的核心优势

  1. 数据安全:通过 private 限制成员变量的直接访问,避免非法数据的输入。
  2. 代码复用:类的成员函数可以被多个对象复用,减少重复代码。
  3. 易于维护:类的内部实现细节被隐藏,修改内部逻辑时,只要对外接口不变,就不会影响外部代码。
  4. 接口清晰:对外只暴露必要的成员函数,让使用者无需关注内部实现,降低学习和使用成本。

5.1 C++ 类的开发规范

  • 成员变量尽量设置为 private,通过 publicget/set 函数访问和修改。
  • 构造函数要保证成员变量的初始化,避免出现未初始化的“脏数据”。
  • 涉及动态内存分配的类,必须手动编写析构函数释放资源,防止内存泄漏。
  • 类的命名采用大驼峰命名法,如 PersonCircle;成员函数和成员变量采用小驼峰命名法,如 setInforadius

六、本章总结

✅ 类是属性和行为的抽象,对象是类的具体实例,二者是面向对象编程的基础。
✅ 封装的核心是通过 public/protected/private 控制访问权限,隐藏实现细节,暴露统一接口。
✅ 构造函数负责对象初始化,支持重载;析构函数负责资源清理,不能重载。
✅ 合理使用封装特性,可以显著提升代码的安全性、复用性和可维护性。

Read more

OpenClaw相关的开源AI项目汇总大全:本文涵盖近期所有OpenClaw相关的GitHub高星star热门项目

OpenClaw相关的开源AI项目汇总大全:本文涵盖近期所有OpenClaw相关的GitHub高星star热门项目

OpenClaw相关的开源AI项目汇总大全:本文涵盖近期所有OpenClaw相关的GitHub高星star热门项目 💡 导读 GitHub上这些OpenClaw开源项目,Star数为什么能破千?我们扒了13个宝藏仓库后发现… 有人用OpenClaw给钉钉搭了智能助手,有人在飞书里养了个AI女友Clawra,还有人把记忆层memU玩成了第二大脑——而这些全部免费开源! 2026年OpenClaw热度飙升,但官方文档晦涩、部署门槛高劝退无数人?别慌!本文汇总了OpenClawInstaller、OneClaw、Moltworker等13个硬核开源项目,覆盖:✅ 一键部署工具(零代码上手)✅ 钉钉/企微/飞书/微信全平台接入方案✅ 云端托管+本地Sandbox双模式✅ 记忆层memU、技能库Skills、甚至AI女友Clawra… 收藏这一篇,省掉你100个小时的踩坑时间! 文章目录 * OpenClaw相关的开源AI项目汇总大全:本文涵盖近期所有OpenClaw相关的GitHub高星star热门项目 * 💡 导读 * 一、OpenClawInstall

By Ne0inhk
手把手教你GitHub访问加速的8种姿势(亲测有效版)

手把手教你GitHub访问加速的8种姿势(亲测有效版)

文章目录 * 一、为什么我的GitHub比蜗牛还慢?(真实原因大揭秘) * 二、8大加速方案实测对比(附成功率评分) * 方案1:镜像站大法(成功率⭐️⭐️⭐️⭐️) * 方案2:Hosts文件改造术(成功率⭐️⭐️⭐️⭐️⭐️) * 方案3:SSH协议加速(成功率⭐️⭐️⭐️) * 方案4:Git配置全局代理(程序员必备) * 方案5:油猴脚本加持(小白神器) * 方案6:CDN加速黑科技 * 方案7:DevSidecar工具(一键加速) * 方案8:终极方案——Gitee中转 * 三、各方案适用场景对比表 * 四、个人私藏加速方案(2023最新) * 五、冷知识:GitHub官方加速通道 * 六、常见问题解答 一、为什么我的GitHub比蜗牛还慢?(真实原因大揭秘) 每次打开GitHub都要转圈半小时?clone代码速度只有10kb/s?这其实是典型的"网络迷航症"

By Ne0inhk
Windows 系统部署 清华团队开源的 Kronos 金融 K 线基础模型——基于 EPGF 架构

Windows 系统部署 清华团队开源的 Kronos 金融 K 线基础模型——基于 EPGF 架构

【EPGF 白皮书】路径治理驱动的多版本 Python 架构—— Windows 环境治理与 AI 教学开发体系 【00】EPGF 架构搭建教程之 总揽篇 【收藏级】Windows AI 本地开发「完全体」环境搭建清单 Windows 系统部署 Kronos 金融 K 线基础模型 ——基于 EPGF 架构 Kronos 仓库介绍 Kronos 是一个针对金融 K 线序列的开源基础模型项目,专为金融市场 "语言" 设计。以下是该仓库的主要信息: 项目概述 Kronos 是首个针对金融烛台图(K 线)的开源基础模型,训练数据来自超过 45 个全球交易所。它采用两阶段框架:

By Ne0inhk

GitHub Actions集成PyTorch-CUDA-v2.6镜像实现CI/CD自动化

GitHub Actions 集成 PyTorch-CUDA-v2.6镜像实现CI/CD自动化 在现代 AI 工程实践中,一个令人头疼的问题始终存在:为什么代码在本地跑得好好的,一到 CI 环境就报错?更别提那些依赖 CUDA 的深度学习项目——“PyTorch 安装失败”、“cuDNN 不兼容”、“GPU 无法识别”……这类问题不仅拖慢迭代节奏,还让新成员望而却步。 尤其当团队开始尝试将模型训练、推理测试纳入自动化流程时,传统手工配置环境的方式彻底暴露短板。你是否也经历过这样的场景:为了验证一次小改动,手动登录服务器、激活虚拟环境、检查驱动版本、重启 Docker 容器?这一套操作下来,半小时没了。 真正的解决方案不是靠“经验”,而是靠标准化和自动化。如果我们能像部署 Web 应用一样,把整个 GPU 计算环境打包成一个可复用的镜像,并通过代码提交自动触发端到端验证,会怎样? 这正是本文要展示的实践路径:

By Ne0inhk