C++_如何高效且安全的编程(数据抽象)特性详解

今天我们梳理了一下数据封装、数据抽象与接口,其实有之前的基础这里也很容易理解。封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全。数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制, C++ 通过创建类来支持封装和数据隐藏(public、protected、 private)。

在软件开发中,数据抽象是一个核心概念,它允许我们隐藏实现细节,仅通过公共接口与外部世界交互。这种封装机制不仅提高了代码的安全性,还促进了代码的复用和可维护性。C++作为一门强大的面向对象编程语言,通过类(Classes)和接口(Interfaces,尽管C++标准库中不直接称为“接口”,但可以通过纯虚类实现)等机制,提供了强大的数据抽象能力。

让我们举一个现实生活中的真实例子,比如一台电视机,您可以打开和关闭、切换频道、调整音量、添加外部组件(如喇叭、录像机、DVD 播放器),但是您不知道它的内部实现细节,也就是说,您并不知道它是如何通过缆线接收信号,如何转换信号,并最终显示在屏幕上。

因此,我们可以说电视把它的内部实现和外部接口分离开了,您无需知道它的内部实现原理,直接通过它的外部接口(比如电源按钮、遥控器、声量控制器)就可以操控电视。

现在,让我们言归正传,就 C++ 编程而言,C++ 类为数据抽象提供了可能。它们向外界提供了大量用于操作对象数据的公共方法,也就是说,外界实际上并不清楚类的内部实现。

优点


提高代码安全性:通过封装,可以限制对类内部状态的直接访问,从而避免数据被意外修改。
增强代码复用性:通过定义清晰的接口,可以在多个项目或模块中重用类。
简化代码维护:由于隐藏了实现细节,当内部实现发生变化时,只需确保接口保持不变,即可减少对外部代码的影响。
提高可读性:通过清晰的接口定义,可以更容易地理解代码的功能和用途。

数据抽象

在C++中,数据抽象主要通过类来实现。类是一种用户定义的类型,它封装了数据成员(属性)和成员函数(行为),其中成员函数可以访问和修改数据成员,但外部代码通常只能通过成员函数来间接访问这些数据成员。

在C++中定义一个类,你需要指定类的名称、数据成员(私有或保护)和成员函数(公有、保护或私有)。通常,数据成员被声明为私有(private),以保护其不受外部直接访问;成员函数被声明为公有(public),以提供类的接口。请看下面的实例:

#include <iostream>
using namespace std;

class Adder{
   public:
      // 构造函数
      Adder(int i = 0)
      {
        total = i;
      }
      // 对外的接口
      void addNum(int number)
      {
          total += number;
      }
      // 对外的接口
      int getTotal()
      {
          return total;
      };
   private:
      // 对外隐藏的数据
      int total;
};
int main( )
{
   Adder a;
   
   a.addNum(10);
   a.addNum(20);
   a.addNum(30);

   cout << "Total " << a.getTotal() <<endl;
   return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

Total 60

上面的类把数字相加,并返回总和。公有成员 addNum 和 getTotal 是对外的接口,用户需要知道它们以便使用类。私有成员 total 是用户不需要了解的,但又是类能正常工作所必需的。

抽象把代码分离为接口和实现。所以在设计组件时,必须保持接口独立于实现,这样,如果改变底层实现,接口也将保持不变。

在这种情况下,不管任何程序使用接口,接口都不会受到影响,只需要将最新的实现重新编译即可。

抽象类与接口

以前的文章已经学习了抽象与接口,今天涉及到安全性,进行一下总结,抽象类是指至少有一个纯虚函数的类。抽象类不能被实例化,只能作为基类被继承。它提供了一个接口,要求派生类实现特定的功能。

通过在函数声明后加 = 0 来定义纯虚函数。

class Shape {
public:
    virtual double area() = 0; // 纯虚函数
};

在 C++ 中,接口通常是一个只包含纯虚函数的抽象类。派生类必须实现这些虚函数,才能创建实例。接口定义了行为,但不提供实现。

class Shape {
public:
    virtual double area() = 0; // 纯虚函数
    virtual void draw() = 0; // 另一个纯虚函数
};
 
class Circle : public Shape {
private:
    double radius;
 
public:
    Circle(double r) : radius(r) {}
 
    double area() override {
        return 3.14159 * radius * radius; // 实现面积计算
    }
 
    void draw() override {
        cout << "Drawing Circle" << endl; // 实现绘制
    }
};
 
class Square : public Shape {
private:
    double side;
 
public:
    Square(double s) : side(s) {}
 
    double area() override {
        return side * side; // 实现面积计算
    }
 
    void draw() override {
        cout << "Drawing Square" << endl; // 实现绘制
    }
};

1、抽象类 Shape

Shape 是一个抽象类,不能直接实例化。它定义了两个纯虚函数:

area():计算形状的面积。
draw():绘制形状。
纯虚函数:通过在函数名后添加 = 0,表示这是一个纯虚函数,要求所有派生类必须实现这些函数。这样,Shape 类提供了一个接口,定义了所有形状必须具备的功能。

2. 派生类 Circle

继承:Circle 类从 Shape 类继承,表示 Circle 是一种形状。

构造函数:Circle(double r) 构造函数用于初始化 Circle 对象的半径。

实现纯虚函数:

area():实现了计算圆的面积的逻辑。
draw():实现了绘制圆的逻辑,输出 "Drawing Circle"。

抽象类 Shape:定义了通用的形状接口(area 和 draw),不提供具体实现,确保所有形状类(如 Circle 和 Square)必须提供这些功能。

派生类 Circle 和 Square:这两个类实现了 Shape 接口,提供了各自特定的形状的行为。

通过使用抽象类和接口,代码变得更加灵活和可扩展。你可以轻松地添加新的形状类,而不需要修改已有的代码,只需确保新类实现 area 和 draw 函数即可。这种设计降低了代码的耦合度,提高了可维护性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/884875.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大厂面试真题-说一下Mybatis的缓存

首先看一下原理图 Mybatis提供了两种缓存机制&#xff1a;一级缓存&#xff08;L1 Cache&#xff09;和二级缓存&#xff08;L2 Cache&#xff09;&#xff0c;旨在提高数据库查询的性能&#xff0c;减少数据库的访问次数。注意查询的顺序是先二级缓存&#xff0c;再一级缓存。…

MySQL Performance Schema 详解及运行时配置优化

引言 MySQL 的 Performance Schema 是一套性能监控与诊断工具&#xff0c;帮助开发者和数据库管理员收集、分析 MySQL 实例的运行状态&#xff0c;找出性能瓶颈并进行优化。通过 Performance Schema&#xff0c;我们能够监控不同的内部事件、线程、会话、语句执行等关键性能指…

Java-数据结构-Map和Set-(二)-哈希表 |ू・ω・` )

文本目录&#xff1a; ❄️一、哈希表&#xff1a; ☑ 1、概念&#xff1a; ☑ 2、冲突-概念&#xff1a; ☑ 3、冲突-避免&#xff1a; ☞ 1&#xff09;、避免冲突-哈希函数的设计&#xff1a; ☞ 2&#xff09;、避免冲突-负载因子调节(重点)&#xff1a; ☑ 4、冲突-解决&…

cloud-(Nacos)--注册中心原理-服务注册-服务发现

并且通过(RestTemplate)Http请求实现了跨微服务的远程调用。不过这种手动发送Http请求的方式存在一些问题 在大型微服务项目中,服务提供者的数量会非常多,为了管理这些服务就引入了注册中心的概念。注册中心、服务提供者、服务消费者三者间关系如下: 流程如下: 服务启动…

Mac安装Manim并运行

1.在macOS上创建Python虚拟环境&#xff0c;可以使用venv模块&#xff0c;这是Python自带的库&#xff0c;也可以使用conda。以下是使用venv创建和使用Python虚拟环境的步骤&#xff1a; 打开终端。 创建一个新的目录来存放你的项目&#xff0c;并进入该目录&#xff1a; mk…

15.安卓逆向-frida基础-HOOK类方法1

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;图灵Python学院 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要盲目相信。 工…

WEB服务器——Tomcat

服务器是可以使用java完成编写&#xff0c;是可以接受页面发送的请求和响应数据给前端浏览器的&#xff0c;而在开发中真正用到的Web服务器&#xff0c;我们不会自己写的&#xff0c;都是使用目前比较流行的web服务器。 如&#xff1a;Tomcat 1. 简介 Tomcat 是一个开源的轻量…

【CAM350】使用总结 <二>{ 光绘Gerber 比较 }

一、 比较两份版本不同的光绘文件&#xff1a; //Analysis-Compare layers// 二、参数默认&#xff0c;比较完成给出结果 三、也可以直接在一份文件上选择“Draw on top” 四、对比差距直观可见

家中浮毛太多怎么办?希喂、米家、安德迈更推荐哪款?

在现代养宠家庭生活中&#xff0c;宠物空气净化器已经成为不可或缺的家电之一。 而在众多空气净化器类型中&#xff0c;宠物空气净化器以其独特的设计和卓越的净化效果&#xff0c;逐渐赢得了越来越多养宠家庭的青睐。 它不仅能有效地吸附空中飞舞的浮毛&#xff0c;还能高效…

基于SSM+小程序的在线课堂微信管理系统(在线课堂1)(源码+sql脚本+视频导入教程+文档)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 &emsp1、管理员实现了首页、个人中心、用户管理、课程分类管理、课程信息管理、课程订阅管理、课程视频管理、公告栏管理、留言板管理、系统管理。 2、用户实现了首页、课程信息、公…

此连接非私人连接

当你手机浏览器输入网站打开提示“此连接非私人连接&#xff0c;此网站可能在冒充来窃取你的个人或财务信息。你应回到之前的页面”这是因为该网站的SSL数字证书到期导致&#xff0c;需要此网站的管理员重新申请数字证书替换之前的文件才可以实现。 注意&#xff1a;如果你不是…

实用SQL小总结

WHERE 条件 column 为纯英文字符 或 不包含任何字符 语法&#xff1a; SELECT * FROM your_table WHERE REGEXP(your_column,^[A-Za-z]$); SELECT * FROM your_table WHERE NOT REGEXP(your_column,^[A-Za-z]$);例&#xff1a; SELECT DISTINCT t.pldlibho FROM kibb_pldlyw…

LLM - 使用 vLLM 部署 Qwen2-VL 多模态大模型 (配置 FlashAttention) 教程

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/142528967 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 vLLM 用…

02-ZYNQ linux开发环境安装,基于Petalinux2022.2和Vitis2022.2

petalinux安装 Petalinux 工具是 Xilinx 公司推出的嵌入式 Linux 开发套件&#xff0c;包括了 u-boot、Linux Kernel、device-tree、rootfs 等源码和库&#xff0c;以及 Yocto recipes&#xff0c;可以让客户很方便的生成、配置、编译及自定义 Linux 系统。Petalinux 支持 Ver…

uniapp EChars图表

1. uniapp EChars图表 &#xff08;1&#xff09;Apache ECharts 一个基于 JavaScript 的开源可视化图表库   https://echarts.apache.org/examples/zh/index.html &#xff08;1&#xff09;官网图例 &#xff08;2&#xff09;个人实现图例 1.1. 下载echart 1.1.1. 下…

docker - 迁移和备份

文章目录 1、docker commit1.1、查询 容器 docker ps1.2、docker commit zookeeper zookeeper:3.4.13 2、docker save -o2.1、宿主机 切换到 /opt 目录下2.2、将镜像保存到 宿主机/opt目录下 3、docker load -i 对某一个容器修改完毕以后&#xff0c;我们可以把最新的容器部署到…

【文心智能体 | AI大师工坊】如何使用智能体插件,完成一款旅游类智能体的开发,来体验一下我的智能体『​​​​​​​厦门CityWalk』

目录 1.1、智能体运行效果 1.2、创作灵感来源 1.3、如何制作智能体 1.4、可能会遇到的几个问题 1.5、快速调优指南 『厦门CityWalk&#x1f680;』我的优质智能体&#xff1a;https://0nxj3k.smartapps.baidu.com/?_swebfr1&_swebScene3621000000000000 在当今这个全…

Bytebase 2.22.3 - 一键回滚 PostgreSQL DML 变更

&#x1f680; 新功能 支持一键回滚 PostgreSQL DML 变更。 &#x1f384; 改进 优化 DML 事前备份和回滚体验&#xff1a; 引导用户创建 bbdataarchive 数据库。如果没有 bbdataarchive 数据库&#xff0c;无法开启备份功。用户现在可以在创建工单之后开启或关闭备份功能&a…

Python | Leetcode Python题解之第437题路径总和III

题目&#xff1a; 题解&#xff1a; class Solution:def pathSum(self, root: TreeNode, targetSum: int) -> int:prefix collections.defaultdict(int)prefix[0] 1def dfs(root, curr):if not root:return 0ret 0curr root.valret prefix[curr - targetSum]prefix[cu…

ROS学习笔记(四):使用 `ros2 run usb_cam usb_cam_node_exe` 启动 USB 摄像头

文章目录 前言1 安装 usb_cam 包2 启动 USB 摄像头3 订阅相机发布的节点信息并进行可视化3.1 使用 rqt_image_view3.2 使用 image_view3.3 使用 rviz 4 常见问题与解决方案4.1 摄像头未被识别4.2 相机显示异常4.3 如何指定不同的相机4.4 摄像头参数调整 5. 调试信息 5. 结论 前…