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

c++--------------------------------接口实现

  1. 引用参数

    • 引用的基本概念
      • 在C++中,引用是一个别名,它为已存在的变量提供了另一个名字。引用的声明格式为类型& 引用名 = 变量名;。例如,int num = 10; int& ref = num;,这里ref就是num的引用,对ref的操作等价于对num的操作。引用在定义时必须初始化,并且一旦初始化后,就不能再引用其他变量。
    • 引用作为函数参数的优势
      • 避免复制开销:当函数参数是大型对象(如包含大量数据的结构体或类)时,使用引用参数可以避免对象的复制。例如,假设有一个Person类,包含姓名、年龄、地址等多个成员,如果要将Person对象传递给一个函数来修改它的某些属性,使用引用传递可以避免复制整个Person对象的开销。
      class Person {
      public:
        std::string name;
        int age;
        //...其他成员
      };
      void updatePerson(Person& p) {
        p.age++;
      }
      
      • 直接修改原始数据:引用参数允许函数直接修改调用者提供的原始变量。这在需要在函数内部修改外部变量状态的场景中非常有用。例如,在一个函数中交换两个变量的值:
      void swap(int& a, int& b) {
        int temp = a;
        a = b;
        b = temp;
      }
      
    • 引用参数的注意事项
      • 因为引用参数可以修改原始数据,所以在使用时需要谨慎,确保函数的行为符合预期,不会产生意外的副作用。例如,如果一个函数不应该修改传入的参数,但是却使用了引用参数并且在函数内部修改了它,这可能会导致程序出现错误。
        在这里插入图片描述
  2. 接口与实现

    • 接口的定义和作用
      • 定义:接口是一组函数声明的集合,它规定了一个模块(如类、库等)对外提供的功能和服务。接口就像是一个契约,规定了使用者可以调用哪些函数以及这些函数的参数和返回值类型等信息。例如,一个简单的图形绘制接口可能包括drawCircledrawRectangle等函数声明,使用者可以通过这个接口来绘制不同的图形,而不需要了解这些图形是如何具体绘制的(实现细节)。
      • 作用:接口的主要作用是隐藏实现细节,实现模块之间的低耦合。它使得不同的模块可以独立开发和维护,只要它们遵循相同的接口约定。例如,一个游戏开发团队中,图形渲染模块可以通过接口提供给游戏逻辑模块使用,游戏逻辑模块只需要调用接口中的函数来请求渲染图形,而不必关心图形是如何在屏幕上渲染出来的(这是图形渲染模块的实现细节)。
    • 实现的概念和方式
      • 概念:实现是指对接口中声明的函数进行具体的定义,以实现接口规定的功能。例如,对于前面提到的图形绘制接口,实现部分可能包括如何根据参数在屏幕上绘制圆形、矩形等图形的具体算法和代码。
      • 方式:在C++中,如果接口是以类的形式定义的,那么实现通常是在类的成员函数定义中完成。例如,对于一个Shape接口类(包含纯虚函数),具体的形状类(如CircleRectangle)会继承Shape类并实现其中的纯虚函数:
      class Shape {
      public:
        virtual void draw() = 0;
      };
      class Circle : public Shape {
      public:
        void draw() override {
          // 具体的圆形绘制实现代码
        }
      };
      class Rectangle : public Shape {
      public:
        void draw() override {
          // 具体的矩形绘制实现代码
        }
      };
      
  3. 接口设计原则

    • 单一职责原则(SRP)
      • 含义:一个接口(或类)应该只有一个引起它变化的原因。也就是说,接口应该专注于提供一组紧密相关的功能。例如,一个FileReader接口应该只负责文件读取相关的功能,如openFilereadData等,而不应该包含文件写入或其他不相关的功能。
      • 示例和好处:假设我们有一个UserService接口,它包含registerUser(用户注册)和loginUser(用户登录)功能。按照单一职责原则,这个接口专注于用户认证相关的功能。这样,如果以后需要修改用户注册的逻辑(比如添加新的验证规则)或者用户登录的逻辑(比如支持多因素认证),这些修改不会影响到其他不相关的功能模块,使得代码的维护和扩展更加容易。
    • 接口隔离原则(ISP)
      • 含义:客户端不应该被迫依赖于它不需要的接口。也就是说,应该把大的接口拆分成多个小的、更具体的接口,让客户端只依赖它真正需要的接口。例如,对于一个图形绘制系统,有一个ComplexGraphics接口包含了高级图形绘制功能(如绘制3D图形)和基本图形绘制功能(如绘制圆形、矩形)。对于一个只需要绘制基本图形的客户端应用,应该提供一个BasicGraphics接口,将基本图形绘制功能分离出来,这样客户端就不需要依赖包含高级图形绘制功能的接口。
      • 示例和好处:假设有一个Printer接口,它包含printText(打印文本)、printImage(打印图像)和printBarcode(打印条形码)三个功能。对于一个只需要打印文本的简单文档处理应用,按照接口隔离原则,可以创建一个TextPrinter接口,只包含printText功能。这样,这个应用只需要依赖TextPrinter接口,而不会因为Printer接口的其他功能(如打印图像或条形码的功能可能会频繁更新或出现问题)而受到影响,提高了系统的稳定性和可维护性。
    • 里氏替换原则(LSP)
      • 含义:派生类(子类)对象能够替换其基类(父类)对象,并且程序的功能不受影响。也就是说,在任何使用基类对象的地方,都可以透明地使用派生类对象,并且程序的行为应该符合预期。例如,有一个Vehicle基类,包含move函数,CarBicycleVehicle的派生类。按照里氏替换原则,CarBicyclemove函数的行为应该与Vehiclemove函数的行为在概念上是一致的,只是具体的移动方式(如速度、行驶路线等)可能不同。
      • 示例和好处:假设我们有一个函数void travel(Vehicle* vehicle),它可以接受任何Vehicle类型的对象,并调用其move函数来模拟行驶。如果CarBicycle类正确地遵循里氏替换原则,我们可以在travel函数中传递CarBicycle对象,而函数的行为(如模拟行驶的逻辑)不会出现错误,这样就使得代码具有更好的扩展性和可维护性,可以方便地添加新的交通工具类型(如Motorcycle等派生类)而不需要对travel函数进行大量修改。
        在这里插入图片描述

http://www.kler.cn/a/449812.html

相关文章:

  • 怎么设置电脑密码?Windows和Mac设置密码的方法
  • 菜鸟带新鸟——基于EPlan2022的部件库制作
  • tcp 的重传,流量控制,拥塞控制
  • VIVO Android面试题及参考答案
  • MySQL数据库——复制表数据与结构
  • UG NX二次开发(C#)-机电概念设计-UIStyler中selection块选择信号等对象的过滤器设置
  • 新能源汽车锂离子电池各参数的时间序列关系
  • C# 范围判断函数
  • 嵌入式Linux QT+OpenCV基于人脸识别的考勤系统 项目
  • 【Where语法全解密】.NET开源ORM框架 SqlSugar 系列
  • 【DOCKER】基于DOCKER的服务之DUFS
  • Java Web 开发学习中:过滤器与 Ajax 异步请求
  • 汽车IVI中控开发入门及进阶(45):凌阳科技车载娱乐芯片
  • 备忘一个FDBatchMove数据转存的问题
  • 驱动性能提升,如何加速基于龙蜥和企业平台的Arm系统开发与部署进程?
  • 通航飞机(通用航空飞机)的软件关键技术
  • 【多模态】swift-3框架使用
  • [react]suspend 组件搭配路由组件时fallback不生效
  • 基于Spring Boot的茶叶商城系统
  • Java基础 | 数据库的命名规范
  • golang断言
  • Android Bootable Recovery 中的 `imgdiff.cpp` 文件解析
  • Zabbix6.0升级为6.4
  • 使用Vue创建前后端分离项目的过程(前端部分)
  • OpenCV(python)从入门到精通——文件操作
  • CSS系列(32)-- Mask详解