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

黑马程序员C++核心编程笔记--4 类和对象--封装

C++面向对象三大特征:封装、继承、多态

C++认为万事万物皆对象,对象有其属性和行为,具有相同性质的对象可以抽象称为

4.1 封装

4.1.1 封装的意义

  • 将属性和行为作为一个整体,表现生活中的事物
  • 将属性和行为加以权限控制

在设计类的时候,属性和行为写在一起,表现事物

语法:class 类名{ 访问权限: 属性/行为}

示例一:设计一个圆类,求圆的周长

#include <iostream>
using namespace std;// 设计一个圆类,求圆的周长
// 圆周率:3.14
const double PI = 3.14;class Circle {
public:// 属性int m_r;    //  半径// 行为// 获取圆的周长double calculateZC() {return 2*PI*m_r;}
};int main() {// 通过圆类创建一个具体的圆(对象)// c就是一个具体的圆(对象)Circle c;c.m_r = 10;     // 给圆对象的半径赋值cout << c.calculateZC() << endl;return 0;
}

示例二:设计一个学生类,属性有姓名和学号,可以给姓名和学号进行赋值,可以显示学生的姓名和学号

#include <iostream>
using namespace std;class Student {
public:// 属性string s_name;int m_id;// 行为// 给姓名和学号进行赋值操作void setName(string name) {s_name = name;}void setId(int id) {m_id = id;}// 显示姓名和学号void showInfo() {cout << s_name << " " << m_id << endl;}};int main() {Student s1{"张三", 001};s1.showInfo();Student  s2;s2.setName("homo");s2.setId(111);s2.showInfo();
}

4.1.2 访问权限

  • public: 公有属性,类外可以访问
  • private: 私有属性,类外不可以访问
  • protected: 保护属性,类外不可以访问,类内可以访问,子类可以访问

示例:

#include <iostream>
using namespace std;class Person {// 姓名 公共权限public:string m_name;// 汽车 保护权限protected:string m_car;// 银行密码 私有权限private:int m_password;// 行为public:void func() {m_name = "张三";m_car = "保时捷";m_password = 123456;}void showInfo() {cout << "姓名:" << m_name << endl;cout << "汽车:" << m_car << endl;cout << "密码:" << m_password << endl;}
};int main() {Person p1;p1.m_name = "homo";cout << p1.m_name << endl;// p1.m_car = "拖拉机"; 报错,保护权限类外无法访问// cout << p1.m_car << endl;// p1.m_password = 987654; 报错,私有权限类外无法访问// cout << p1.m_password << endl;Person p2;p2.func();cout << p2.m_name << endl;// cout << p2.m_car << endl; 同样报错,只能通过公开函数访问// cout << p2.m_password << endl; 同样报错,只能通过公开函数访问p2.showInfo();      // 正确,通过公开函数访问
}

4.1.3 C++中class和struct的区别

在C++中 struct和class唯一的区别就在于默认的访问权限不同

区别:

  • struct 默认属性是public
  • class 默认属性是private

示例:

#include <iostream>using namespace  std;class c1 {int m_a;    // 默认是私有变量
};struct s1 {int m_a;    // 默认是公共变量
};int main() {c1 c;s1 s;// c.m_a = 1;   错误,私有变量不能被访问s.m_a = 2;      //  正确,公共变量可以被访问// cout << c.m_a << endl;   错误,私有变量不能被访问cout << s.m_a << endl;      //  正确,公共变量可以被访问return 0;
}

4.1.4成员属性设置为私有

  • 优点1:可以自己控制读写权限
  • 优点2:对于写权限,我们可以检测数据的有效性

示例:

#include <iostream>
#include <string>using namespace std;class Person {// 公有方法对私有属性进行控制
public:// 姓名:可读可写// 姓名的写操作:设置姓名void setName(string name) {m_Name = name;}// 姓名的读操作:获取姓名string getName() {return m_Name;}// 年龄设置可读可写// 获取年龄int getAge() {return m_Age;}// 年龄设置可读可写void setAge(int age) {if (age >= 0 && age <= 150)m_Age = age;else {cout << "年龄需要在0-150之间" << endl;return;   // 年龄输入有误,返回}}// 情人设置可写void setLover(string lover) {m_lover = lover;}
private:string m_Name;  // 姓名 可读可写int m_Age = 18;  //  年龄 可读可写,但只能在0-150之间string m_lover; // 情人 只写};int main() {Person p;// 写姓名p.setName("aj");// 读姓名cout << "姓名:" << p.getName() << endl;// 写年龄p.setAge(20);// 读年龄cout << "年龄:" << p.getAge() << endl;return 0;
}

4.1.5 设计案例1 立方体类

设计立方体类(Cube),求出立方体的面积体积

分别用全局函数成员函数判断两个立方体是否相等。

示例:

//
// 设计立方体类(Cube),求出立方体的面积和体积。
// 分别用全局函数和成员函数判断两个立方体是否相等。
//
#include <iostream>
using namespace std;class Cube
{// 属性
private:double m_L;     //长double m_W;     //宽double m_H;     //高// 行为
public:// 属性为私有,设置方法获取长宽高// 设置长void setL(double L) {m_L = L;}// 获取长double getL() {return m_L;}// 设置宽void setW(double W) {m_W = W;}// 获取宽double getW() {return m_W;}// 设置高void setH(double H) {m_H = H;}// 获取高double getH() {return m_H;}// 求立方体的面积double getArea() {return 2*(m_L*m_W+m_L*m_H+m_W*m_H);}// 求立方体的体积double Volume() {return m_L*m_W*m_H;}// 成员函数判断两个立方体是否相等bool isEqualByClass(Cube & c) {if (m_L == c.getL() && m_W == c.getW() && m_H == c.getH())return true;elsereturn false;}
};// 全局函数:判断两个立方体是否相等
// 思路:分别比较两个立方体的长宽高是否相等,如果相等则认为两个立方体相等
bool isEqual(Cube & c1, Cube & c2) {if (c1.getL() == c2.getL() && c1.getW() == c2.getW() && c1.getH() == c2.getH())return true;elsereturn false;
}int main()
{// 实例化两个立方体Cube c1;c1.setL(10);c1.setW(20);c1.setH(30);cout << "c1的面积为:" << c1.getArea() << endl;cout << "c1的体积为:" << c1.Volume() << endl;cout << "--------------------" << endl;Cube c2;c2.setL(10);c2.setW(20);c2.setH(30);cout << "c2的面积为:" << c2.getArea() << endl;cout << "c2的体积为:" << c2.Volume() << endl;cout << "--------------------" << endl;// 全局函数判断两个立方体是否相等bool a = isEqual(c1, c2);if (a)cout << "两个立方体相等" << endl;elsecout << "两个立方体不相等" << endl;cout << endl;// 成员函数判断两个立方体是否相等bool b = c1.isEqualByClass(c2);if (b)cout << "成员函数判断:两个立方体相等" << endl;elsecout << "成员函数判断:两个立方体不相等" << endl;
}

4.1.6 设计案例2 点和圆关系

设计一个圆形类(Circle),和一个点类(Point),计算点和圆的关系。

示例:

//
// 设计一个圆形类(Circle),和一个点类(Point),计算点和圆的关系。
//
#include <iostream>
using namespace std;// 点类
class Point {private:int m_X;int m_Y;// 对外提供公有接口
public:// 设置x坐标void SetX(int x) {m_X = x;}// 获取x坐标int GetX() {return m_X;}// 设置y坐标void SetY(int y) {m_Y = y;}// 获取y坐标int GetY() {return m_Y;}
};
// 圆类
class Circle {
private:// 半径int m_R;// 圆心Point m_Center;     // 在类中可以让另一个类的属性作为成员变量public:// 设置半径void setR(int r) {m_R = r;}// 获取半径int getR() {return m_R;}// 设置圆心void setCenter(Point center) {m_Center = center;}// 获取圆心Point getCenter() {return m_Center;}};
// 判断点和圆的关系
// 圆心到点距离小于半径,则点在圆内;圆心到点距离大于半径,则点在圆外;圆心到点距离等于半径,则点在圆上。
void isInCircle(Circle &c, Point &p) {// 点到圆心距离计算公式:sqrt((x1-x2)^2 + (y1-y2)^2)// 简化代码:既然只要我们比较点到圆心的距离与半径,那么可以省去点到远近距离计算的根号,用左侧和右侧同时平方进行比较。// 计算两点之间距离的平方int distance = (c.getCenter().GetX()-p.GetX())*(c.getCenter().GetX()-p.GetX()) +(c.getCenter().GetY()-p.GetY())*(c.getCenter().GetY()-p.GetY());// 计算半径的平方int rDistance = c.getR() * c.getR();// 判断关系if (distance < rDistance) {cout << "点在圆内" << endl;}else if (distance > rDistance) {cout << "点在圆外" << endl;}else {cout << "点在圆上" << endl;}
}
int main() {// 创建圆Circle c;c.setR(10);Point center;   // 创建圆心center.SetX(10);center.SetY(0);c.setCenter(center);cout << "圆的半径为:" << c.getR() << endl;cout << "圆的圆心为:" << c.getCenter().GetX() << " " << c.getCenter().GetY() << endl;// 创建点Point p;p.SetX(10);p.SetY(10);// 判断关系isInCircle(c, p);return 0;
}

相关文章:

黑马程序员C++核心编程笔记--4 类和对象--封装

C面向对象三大特征&#xff1a;封装、继承、多态 C认为万事万物皆对象&#xff0c;对象有其属性和行为&#xff0c;具有相同性质的对象可以抽象称为类 4.1 封装 4.1.1 封装的意义 将属性和行为作为一个整体&#xff0c;表现生活中的事物将属性和行为加以权限控制 在设计类…...

Debian:自由操作系统的精神图腾与技术基石

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 ——解码Linux世界最纯粹的开源哲学 一、Debian的诞生&#xff1a;从个人实验到全球协作 1993年&#xff0c;一位名为Ian Murdock的程序员在开源社区的启…...

云计算Linux Rocky day02(安装Linux系统、设备表示方式、Linux基本操作)

云计算Linux Rocky day02&#xff08;安装Linux系统、设备表示方式、Linux基本操作&#xff09; 目录 云计算Linux Rocky day02&#xff08;安装Linux系统、设备表示方式、Linux基本操作&#xff09;1、虚拟机VMware安装Rocky2、Linux命令行3、Linux Rocky修改字体大小和背景颜…...

在 ODROID-H3+ 上安装 Win11 系统

在 ODROID-H3 上安装 Windows 11 系统。 以下是完整的步骤&#xff0c;包括 BIOS 设置、U 盘制作、安装和驱动处理&#xff0c;全程不保留之前的系统数据。 ✅ 准备工作 1. 准备一个 ≥8GB 的 USB 启动盘 用另一台电脑制作 Windows 11 安装盘。 &#x1f449; 推荐工具&…...

Docker常用命令操作指南(一)

Docker常用命令操作指南-1 一、Docker镜像相关命令1.1 搜索镜像&#xff08;docker search&#xff09;1.2 拉取镜像&#xff08;docker pull&#xff09;1.3 查看本地镜像&#xff08;docker images&#xff09;1.4 删除镜像&#xff08;docker rmi&#xff09; 二、Docker容器…...

什么是 SQL 注入?如何防范?

什么是 SQL 注入?如何防范? 1. SQL 注入概述 1.1 基本定义 SQL 注入(SQL Injection)是一种通过将恶意SQL 语句插入到应用程序的输入参数中,从而欺骗服务器执行非预期SQL命令的攻击技术。攻击者可以利用此漏洞绕过认证、窃取数据甚至破坏数据库。 关键结论:SQL 注入是O…...

使用el-input数字校验,输入汉字之后校验取消不掉

先说说复现方式 本来input是只能输入数字的&#xff0c;然后你不小心输入了汉字&#xff0c;触发校验了&#xff0c;然后这时候&#xff0c;你发现校验取消不掉了 就这样了 咋办啊&#xff0c;你一看校验没错啊&#xff0c;各种number啥的也写了,发现没问题啊 <el-inputv…...

Docker容器启动失败的常见原因分析

我们在开发部署的时候&#xff0c;用 Docker 打包环境&#xff0c;理论上是“我装好了你就能跑”。但理想很丰满&#xff0c;现实往往一 docker run 下去就翻车了。 今天来盘点一下我实际工作中经常遇到的 Docker 容器启动失败的常见原因&#xff0c;顺便给点 debug 的小技巧&a…...

Java提取markdown中的表格

Java提取markdown中的表格 说明 这篇博文是一个舍近求远的操作&#xff0c;如果只需要要对markdown中的表格数据进行提取&#xff0c;完全可以通过正在表达式或者字符串切分来完成。但是鉴于学习的目的&#xff0c;这次采用了commonmark包中的工具来完成。具体实现过程如下 实…...

立志成为一名优秀测试开发工程师(第七天)——unittest框架的学习

目录 unittest框架的学习 一、测试类的编写 创建相关测试类cal.py、CountTest.py 二、常见断言方法 使用unittest单元测试框架编写测试用例CountTest.py 注意&#xff1a;执行的时候光标一定要放在括号后面&#xff0c;鼠标右键运行 三、对测试环境的初始化和清除模块…...

精益数据分析(85/126):营收阶段的核心指标与盈利模型优化——从数据到商业决策的落地

精益数据分析&#xff08;85/126&#xff09;&#xff1a;营收阶段的核心指标与盈利模型优化——从数据到商业决策的落地 c。 一、营收健康度的核心指标&#xff1a;投资回报率模型 &#xff08;一&#xff09;季度再发性营收增长率&#xff08;QRR&#xff09; 该指标衡量…...

论坛系统(4)

用户详情 获取用户信息 实现逻辑 ⽤⼾提交请求&#xff0c;服务器根据是否传⼊Id参数决定返回哪个⽤⼾的详情 1. 不传⽤⼾Id&#xff0c;返回当前登录⽤⼾的详情(从session获取) 2. 传⼊⽤⼾Id&#xff0c;返回指定Id的⽤⼾详情(根据用户id去查) 俩种方式获得用户信息 参…...

本地Markdown开源知识库选型指南

本地Markdown开源知识库选型指南 以下是几款优秀的本地Markdown开源知识库解决方案&#xff0c;适合不同需求场景&#xff1a; 1. Obsidian (非完全开源但免费) 特点&#xff1a;基于Markdown的本地优先知识管理&#xff0c;丰富的插件生态优势&#xff1a;双向链接、图形视…...

【.net core】SkiaSharp 如何在Linux上实现

1. 安装依赖库 首先需要安装 SkiaSharp 运行时依赖&#xff1a; # Ubuntu/Debian sudo apt-get update sudo apt-get install -y libfontconfig1 libfreetype6 libx11-6 libx11-xcb1 libxcb1 \libxcomposite1 libxcursor1 libxdamage1 libxi6 libxtst6 \libnss3 libcups2 lib…...

后端项目中静态文案国际化语言包构建选型

这是一个很关键的问题。在做国际化&#xff08;i18n&#xff09;时&#xff0c;不同语言包格式如 .resx、.properties 和 .json 都可用&#xff0c;但各自有适用场景、特性与限制&#xff0c;你在选择时可以根据你的开发语言、生态和维护成本权衡。 ✅ 一张对比表&#xff1a;.…...

前端面经 React常见的生命周期

初始化阶段 constructor state的初始化&#xff0c;防抖节流的绑定getDerivedStateFromProps 静态函数 当作纯函数使用 传入props和state&#xff0c;合并成一个新的statecomponentWillMount 组件如果有getDrivedStatefromprops不会执行 针对一些接口的预请求时使用rendercomp…...

力扣面试150题--二叉树的层平均值

Day 54 题目描述 思路 初次做法&#xff08;笨&#xff09;&#xff1a;使用两个队列&#xff0c;一个队列存放树的节点&#xff0c;一个队列存放对应节点的高度&#xff0c;使用x存放上一个节点&#xff0c;highb存放上一个节点的高度&#xff0c;sum存放当前层的节点值之和…...

【Doris入门】Doris初识:分布式分析型数据库的核心价值与架构解析

目录 1 Doris简介与核心价值 2 Doris架构深度解析 2.1 Frontend&#xff08;FE&#xff09;架构 2.2 Backend&#xff08;BE&#xff09;架构 3 Doris核心概念详解 3.1 数据分布模型 3.2 Tablet与Replica 3.3 数据模型 4 Doris关键技术解析 4.1 存储引擎 4.2 查询执…...

C#面试问题41-60

41. What is the Singleton design pattern? Singleton is a class that only allows creating a single instance of itselt. 单例设计模式是一个类&#xff0c;它只允许创建自己的单个实例。 构造函数防止他在单例类以外的地方被调用。 使用情景&#xff1a;need a sing…...

数据结构与算法学习笔记(Acwing 提高课)----动态规划·区间DP

数据结构与算法学习笔记----动态规划区间DP author: 明月清了个风 first publish time: 2025.5.26 ps⭐️区间DP的特征在于子结构一般是一个子区间上的问题&#xff0c;涉及到的问题也非常多&#xff0c;如环形区间&#xff0c;记录方案数&#xff0c;高精度&#xff0c;二维…...

【合集】Linux——31个普通信号

Linux普通信号总表&#xff08;1-31&#xff09;​​ ​编号​​信号名​​触发原因​​默认动作​1SIGHUP终端连接断开&#xff08;如SSH会话终止&#xff09;或守护进程重载配置&#xff08;如nginx -s reload&#xff09;终止进程2SIGINT用户输入CtrlC中断前台进程终止进程…...

从0到1搭建AI绘画模型:Stable Diffusion微调全流程避坑指南

从0到1搭建AI绘画模型&#xff1a;Stable Diffusion微调全流程避坑指南 系统化学习人工智能网站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目录 从0到1搭建AI绘画模型&#xff1a;Stable Diffusion微调全流程避坑指南摘要引言一、数据集构…...

ASP.NET Core 中JWT的基本使用

文章目录 前言一、JWT与RBAC二、JWT 的作用三、RBAC 的核心思想四、使用1、配置文件 (appsettings.json)2、JWT配置模型 (Entity/JwtSettings.cs)3、服务扩展类&#xff0c;JWT配置 (Extensions/ServiceExtensions.cs)4、用户仓库接口服务5、认证服务 (Interface/IAuthService.…...

未来技术展望

应用场景:海量数据并行处理 技术融合: # 概念代码:量子加速的数据清洗 from quantum_processor import PhotonicProcessordef quantum_data_cleaning(data):# 使用光量子处理器并行处理千万级数据processor = PhotonicProcessor(model="Xanadu Borealis")return …...

从一到无穷大 #46:探讨时序数据库Deduplicate与Compaction的设计权衡

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 文章目录 引言Compaction AlgorithmsCompact Execution Flow Based On VeloxLocalMergeSource的…...

vue3 导出excel

需求&#xff1a;导出自带格式的excel表格 1.自定义二维数组格式 导出 全部代码&#xff1a; <el-button click"exportExcel">导出</el-button> const exportExcel () > {const data [[商品, 单价, 数量, 总价],[A, 100, 1.55, { t: n, f: B2*C2…...

带你手写React中的useReducer函数。(底层实现)

文章目录 前言一、为什么需要 Reducer&#xff1f;二、Reducer 的核心概念1. Reducer 函数2. useReducer 钩子 三&#xff0c;手写react中的useReducer 总结 前言 在 React 开发中&#xff0c;useReducer 是管理复杂状态逻辑的利器。它类似于 Redux 的简化版&#xff0c;允许我…...

day024-网络基础-TCP与UDP、DNS

文章目录 1. 李导推荐书籍2. OSI七层模型2.1 传输层2.2 网络层2.2.1 问&#xff1a;两端处于不同局域网的设备怎么网络通信&#xff1f; 2.3 数据链路层2.4 物理层2.5 图解OSI七层模型 3. 数据传输模式3.1 全双工3.2 半双工3.3 单工 4. TCP 3次握手4.1 抓包 5. TCP 4次挥手5.1 …...

专场回顾 | 重新定义交互,智能硬件的未来设计

自2022年起&#xff0c;中国智能硬件行业呈现出蓬勃发展的态势&#xff0c;市场规模不断扩大。一个多月前&#xff0c;“小智AI”在短视频平台的爆火将智能硬件带向了大众视野&#xff0c;也意味着智能硬件已不再仅仅停留在概念和技术层面&#xff0c;而是加速迈向实际落地应用…...

如何把一台电脑作为另外一台电脑的显示器

https://zhuanlan.zhihu.com/p/703889583 1. 两台电脑都要进行&#xff1a;点开投影到此电脑&#xff0c;点击可选功能&#xff0c;在可选功能窗口&#xff0c;搜索无线显示器&#xff1b;在结果列表中选中无线显示器&#xff0c;并安装 2. 在笔记本电脑&#xff08;要用来做…...