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

C++代码重用:继承与组合的比较

 

目录

一、简介

继承

组合

二、继承

三、组合

四、案例说明

4.1一个电子商务系统

4.1.1继承方式

在上述代码中,Order类继承自User类。通过继承,Order类获得了User类的成员函数和成员变量,并且可以添加自己的特性。我们重写了displayInfo()函数,以便在Order类中显示订单相关信息。4.1.2组合方式


一、简介

当涉及到代码重用时,继承和组合是两种常见的机制。下面将更详细地介绍它们的特点、使用方式以及各自的优缺点。

  1. 继承

    • 特点:继承是一种创建新类的方式,通过继承已有类的属性和方法来构建新类。在继承关系中,子类(也称为派生类)继承了父类(也称为基类)的成员变量和成员函数,并且可以添加自己的特性。
    • 使用方式:在C++中,可以使用classstruct关键字定义类,在定义派生类时,使用冒号:指定继承关系。在继承中,派生类可以访问父类的公有成员,但不能访问私有成员。
    • 优点:
      • 代码重用:通过继承可以重用基类的代码,减少重复编写相似代码的工作量。
      • 层次结构:继承可以创建一个层次结构,通过将类组织成父子关系,可以更好地组织和管理代码。
    • 缺点:
      • 紧耦合:继承会在派生类和基类之间创建紧密的依赖关系,如果基类发生变化,可能会影响到所有的派生类。
      • 多继承问题:多继承可能引发命名冲突和复杂性增加的问题,需要小心处理。
  2. 组合

    • 特点:组合是一种通过在一个类中包含另一个类的对象来实现代码重用的机制。在组合关系中,一个类(称为组合类)包含另一个类(称为成员类)的对象作为成员变量,通过调用成员对象的方法来实现自己的功能。
    • 使用方式:在C++中,可以在组合类中声明成员对象作为成员变量,并在组合类的方法中调用成员对象的方法来实现功能。
    • 优点:
      • 松耦合:组合关系比继承关系更加松散,类之间的依赖关系相对较弱,修改一个类不会影响到其他类。
      • 灵活性:组合允许动态地改变成员对象,可以在运行时替换成员对象,提供更大的灵活性。
    • 缺点:
      • 冗余代码:组合可能导致一些重复代码,需要在组合类中转发成员对象的方法。
      • 对象管理:组合类需要负责创建和管理成员对象,增加了额外的工作量。

在选择使用继承还是组合时,需要考虑以下因素:

  • 类的关系:如果存在一种“is-a”的关系,即派生类是基类的一种特殊形式,可以选择使用继承。例如,Dog可以被视为Animal的一种特殊类型。
  • 代码重用程度:如果需要重用大量基类代码,可以选择继承。继承允许派生类直接使用基类的功能,减少了代码编写的工作量。
  • 灵活性要求:如果需要更灵活的类关系和低耦合度,可以选择组合。组合允许动态替换成员对象,提供更大的灵活性。

二、继承

继承是一种通过创建一个新类来继承已有类的属性和方法的机制。在继承关系中,子类(派生类)可以继承父类(基类)的成员变量和成员函数,并且可以添加自己的特性。下面是一个简单的示例:

#include <iostream>class Animal {
public:void eat() {std::cout << "Animal is eating." << std::endl;}
};class Dog : public Animal {
public:void bark() {std::cout << "Dog is barking." << std::endl;}
};int main() {Dog dog;dog.eat();  // 输出 "Animal is eating."dog.bark(); // 输出 "Dog is barking."return 0;
}

在这个示例中,我们定义了一个基类Animal和一个派生类Dog。派生类Dog继承了基类Animaleat方法,并添加了自己的bark方法。通过创建Dog对象,我们可以调用继承的eat方法和派生类自己的bark方法。

优点:

  1. 代码重用:继承允许派生类重用基类的代码,避免了重复编写相似的代码。
  2. 层次结构:继承可以创建一个层次结构,通过将类组织成父子关系,可以更好地组织和管理代码。

缺点:

  1. 紧耦合:继承会在派生类和基类之间创建紧密的依赖关系,如果基类发生变化,可能会影响到所有的派生类。
  2. 多继承问题:多继承可能会引发命名冲突和复杂性增加的问题。

三、组合

组合是一种通过在一个类中包含另一个类的对象来实现代码重用的机制。在组合关系中,一个类(组合类)包含另一个类(成员类)的对象作为成员变量。下面是一个示例:

#include <iostream>class Engine {
public:void start() {std::cout << "Engine is starting." << std::endl;}
};class Car {
private:Engine engine;public:void start() {engine.start();std::cout << "Car is starting." << std::endl;}
};int main() {Car car;car.start(); // 输出 "Engine is starting." 和 "Car is starting."return 0;
}

在这个示例中,我们定义了一个成员类Engine和一个组合类Car。组合类Car包含一个Engine对象作为成员变量,并通过调用Engine对象的方法实现自己的功能。

优点:

  1. 松耦合:组合关系比继承关系更加松散,类之间的依赖关系相对较弱,修改一个类不会影响到其他类。
  2. 灵活性:组合允许动态地改变成员对象,可以在运行时替换成员对象,提供更大的灵活性。

缺点:

  1. 冗余代码:组合可能导致一些重复代码,需要在组合类中转发成员对象的方法。
  2. 对象管理:组合类需要负责创建和管理成员对象,增加了额外的工作量。

结论: 继承和组合都是C++中常用的代码重用机制,它们各有优缺点。在选择使用哪种机制时,需要根据具体的需求和设计要求进行权衡。如果需要创建一个层次结构或者重用大量基类代码,可以选择继承;如果需要更灵活的类关系和低耦合度,可以选择组合。重要的是根据实际情况选择适合的代码重用方式,并结合良好的设计原则来编写高质量的代码。

四、案例说明

4.1一个电子商务系统

其中有两个重要的类:User(用户)和Order(订单)。用户可以下订单,并且一个用户可以有多个订单,因此User类和Order类之间存在一种关系。我们将使用继承和组合两种方式来设计这两个类之间的关系。

4.1.1继承方式

#include <iostream>
#include <string>// 用户类
class User {
private:std::string name;
public:User(const std::string& name) : name(name) {}void setName(const std::string& newName) {name = newName;}std::string getName() const {return name;}virtual void displayInfo() const {std::cout << "User: " << name << std::endl;}
};// 订单类,继承自用户类
class Order : public User {
private:std::string orderId;
public:Order(const std::string& name, const std::string& orderId): User(name), orderId(orderId) {}void setOrderId(const std::string& newOrderId) {orderId = newOrderId;}std::string getOrderId() const {return orderId;}void displayInfo() const override {std::cout << "User: " << getName() << ", OrderId: " << orderId << std::endl;}
};int main() {User user("John");Order order("John", "12345");user.displayInfo();order.displayInfo();return 0;
}

在上述代码中,Order类继承自User类。通过继承,Order类获得了User类的成员函数和成员变量,并且可以添加自己的特性。我们重写了displayInfo()函数,以便在Order类中显示订单相关信息。4.1.2组合方式

#include <iostream>
#include <string>// 用户类
class User {
private:std::string name;
public:User(const std::string& name) : name(name) {}void setName(const std::string& newName) {name = newName;}std::string getName() const {return name;}void displayInfo() const {std::cout << "User: " << name << std::endl;}
};// 订单类,组合了用户类对象
class Order {
private:std::string orderId;User user;
public:Order(const std::string& name, const std::string& orderId): user(name), orderId(orderId) {}void setOrderId(const std::string& newOrderId) {orderId = newOrderId;}std::string getOrderId() const {return orderId;}void displayInfo() const {std::cout << "User: " << user.getName() << ", OrderId: " << orderId << std::endl;}
};int main() {User user("John");Order order("John", "12345");user.displayInfo();order.displayInfo();return 0;
}

在这个例子中,Order类包含了一个User类的对象作为成员变量。通过组合,Order类可以调用User类的方法来处理用户相关的操作。

总结: 在这个案例中,我们展示了继承和组合两种不同的代码重用方式。继承适用于存在"是一种"关系的类,并且可以直接使用基类的成员函数和成员变量。组合适用于存在"有一个"关系的类,其中一个类作为另一个类的成员变量,通过调用成员对象的方法来实现功能。选择使用继承还是组合取决于具体的需求和设计目标,需要权衡各自的优缺点来做出决策。

相关文章:

C++代码重用:继承与组合的比较

目录 一、简介 继承 组合 二、继承 三、组合 四、案例说明 4.1一个电子商务系统 4.1.1继承方式 在上述代码中&#xff0c;Order类继承自User类。通过继承&#xff0c;Order类获得了User类的成员函数和成员变量&#xff0c;并且可以添加自己的特性。我们重写了displayI…...

暴打小苹果

欢迎来到程序小院 暴打小苹果 玩法&#xff1a;鼠标左键点击任意区域可发招暴打&#xff0c;在苹果到达圆圈时点击更容易击中&#xff0c; 30秒挑战暴打小苹果&#xff0c;打中一次20分&#xff0c;快去暴打小苹果吧^^。开始游戏https://www.ormcc.com/play/gameStart/247 htm…...

【BetterBench】2024年都有哪些数学建模竞赛和大数据竞赛?

2024年每个月有哪些竞赛&#xff1f; 2024年32个数学建模和数据挖掘竞赛重磅来袭&#xff01;&#xff01;&#xff01; 2024年数学建模和数学挖掘竞赛时间目录汇总 一月 &#xff08;1&#xff09;2024年第二届“华数杯”国际大学生数学建模竞赛 报名时间&#xff1a;即日起…...

Vue-9、Vue事件修饰符

1、prevent 阻止默认事件 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>事件修饰符</title><!--引入vue--><script type"text/javascript" src"https://cdn.jsdeliv…...

前端面试题集合六(高频)

1、vue实现双向数据绑定原理是什么&#xff1f; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>…...

使用Pygame库创建了一个窗口,并在窗口中加载了一个名为“ball.png“的图片,通过不断改变物体的位置,实现了一个简单的动画效果

import pygame import sys# 初始化Pygame pygame.init()# 创建窗口 screen pygame.display.set_mode((640, 480))# 加载图片 image pygame.image.load("ball.png")# 将物体初始位置设为屏幕左上角 x 0 y 0# 游戏循环 while True:# 处理事件for event in pygame.e…...

常见的AdX程序化广告交易模式有哪些?媒体如何选择恰当的交易模式?

程序化广告的核心目的是&#xff1a;让需求方能自由地选择流量与出价&#xff0c;程序化广告在数字广告投放中的主导地位日益巩固。 程序化广告“交易模式”有哪些&#xff1f;以下是详细解读&#xff0c;帮助媒体选择恰当的交易方式&#xff0c;从而实现广告价值的最大化。 …...

VCG 网格平滑之Laplacian平滑

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 由于物理采样过程固有的局限性,三维扫描仪获得的网格通常是有噪声的。为了消除这种噪声,所谓的平滑算法被开发出来。这类方法有很多,VCG主要为我们提供了一种是较为经典的Laplace平滑算法,这个方法很多库都有实…...

Jupyter Markdown格式

穿插在程序中&#xff0c;太复杂了喧宾夺主&#xff0c;太简单了不如注释。这样就刚刚好&#xff1a; Headers # header 1 ## header 2 ### header 3 #### header 4Output: header 1 header 2 header 3 header 4 2. Horizontal Line Use any of three to draw a horizon…...

Vue3 实时显示时间

记录一下代码&#xff0c;方便以后使用 参考的文章链接 做了以下修改 修改了formateDate方法中传入参数这个不合理的地方给定时器增加了间隔时间增加了取消定时器的方法 <!-- template中的代码 --> <span>当前时间&#xff1a;{{ nowTime }}</span>// sc…...

详解Java多线程之循环栅栏技术CyclicBarrier

第1章&#xff1a;引言 大家好&#xff0c;我是小黑&#xff0c;工作中&#xff0c;咱们经常会遇到需要多个线程协同工作的情况。CyclicBarrier&#xff0c;直译过来就是“循环屏障”。它是Java中用于管理一组线程&#xff0c;并让它们在某个点上同步的工具。简单来说&#xf…...

ebpf学习

学习ebpf相关知识 参考资料: awesome-ebpf 文章目录 初识准备ebpf.io介绍cilium的介绍内核文档Brendan Greggs Blog 的介绍书籍Learning eBPFWhat is eBPF? 交互式环境视频 基础知识学习学习环境搭建书籍阅读 项目落地流程整理环境搭建内核编译bcc环境变量zliblibelflibbpflib…...

【Linux】Linux系统编程——ls命令

【Linux】Linux 系统编程——ls 命令 1.命令概述 ls 命令是 Linux 和其他类 Unix 操作系统中最常用的命令之一。ls 命令是英文单词 list 的缩写&#xff0c;正如 list 的意思&#xff0c;ls 命令用于列出文件系统中的文件和目录。使用此命令&#xff0c;用户可以查看目录中的…...

QA面试题

1、质量保证(QA)是什么&#xff1f; QA代表质量保证。QA 是一组活动&#xff0c;旨在确保开发的软件满足 SRS 文档中提到的所有规范或要求。QA 遵循 PDCA 循环&#xff1a; 计划/Plan - 计划是质量保证的一个阶段&#xff0c;组织在此阶段确定构建高质量软件产品所需的过程。做…...

【国产mcu填坑篇】华大单片机(小华半导体)一、SPI的DMA应用(发送主机)HC32L136

最近需要用华大的hc32l136的硬件SPIDMA传输&#xff0c;瞎写很久没调好&#xff0c;看参考手册&#xff0c;瞎碰一天搞通了。。。 先说下我之前犯的错误&#xff0c;也是最宝贵的经验&#xff0c;供参考 没多看参考手册直接写&#xff08;即使有点烂仍然提供了最高的参考价值。…...

【前后端的那些事】treeSelect树形结构数据展示

文章目录 tree-selector1. 新增表单组件2. 在父组件中引用3. 父组件添加新增按钮4. 树形组件4.1 前端代码4.2 后端代码 前言&#xff1a;最近写项目&#xff0c;发现了一些很有意思的功能&#xff0c;想写文章&#xff0c;录视频把这些内容记录下。但这些功能太零碎&#xff0c…...

华为OD机试 - 最长子字符串的长度(二)(Java JS Python C)

题目描述 给你一个字符串 s,字符串 s 首尾相连成一个环形,请你在环中找出 l、o、x 字符都恰好出现了偶数次最长子字符串的长度。 输入描述 输入是一串小写的字母组成的字符串 输出描述 输出是一个整数 备注 1 ≤ s.length ≤ 5 * 10^5s 只包含小写英文字母用例 输入alolob…...

【VRTK】【Unity】【游戏开发】更多技巧

课程配套学习项目源码资源下载 https://download.csdn.net/download/weixin_41697242/88485426?spm=1001.2014.3001.5503 【概述】 本篇将较为零散但常用的VRTK开发技巧集合在一起,主要内容: 创建物理手震动反馈高亮互动对象【创建物理手】 非物理手状态下,你的手会直接…...

Spark 读excel报错,scala.MatchError

Spark3详细报错: scala.MatchError: Map(treatemptyvaluesasnulls -> true, location -> viewfs://path.xlsx, inferschema -> false, addcolorcolumns -> true, header -> true) (of class org.apache.spark.sql.catalyst.util.CaseInsensitiveMap)scala代码…...

【漏洞复现】Office365-Indexs-任意文件读取

漏洞描述 Office 365 Indexs接口存在一个任意文件读取漏洞,攻击者可以通过构造精心设计的请求,成功利用漏洞读取服务器上的任意文件,包括敏感系统文件和应用程序配置文件等。通过利用此漏洞,攻击者可能获得系统内的敏感信息,导致潜在的信息泄露风险 免责声明 技术文章…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...

Spring Security 认证流程——补充

一、认证流程概述 Spring Security 的认证流程基于 过滤器链&#xff08;Filter Chain&#xff09;&#xff0c;核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤&#xff1a; 用户提交登录请求拦…...

window 显示驱动开发-如何查询视频处理功能(三)

​D3DDDICAPS_GETPROCAMPRANGE请求类型 UMD 返回指向 DXVADDI_VALUERANGE 结构的指针&#xff0c;该结构包含特定视频流上特定 ProcAmp 控件属性允许的值范围。 Direct3D 运行时在D3DDDIARG_GETCAPS的 pInfo 成员指向的变量中为特定视频流的 ProcAmp 控件属性指定DXVADDI_QUER…...

大模型智能体核心技术:CoT与ReAct深度解析

**导读&#xff1a;**在当今AI技术快速发展的背景下&#xff0c;大模型的推理能力和可解释性成为业界关注的焦点。本文深入解析了两项核心技术&#xff1a;CoT&#xff08;思维链&#xff09;和ReAct&#xff08;推理与行动&#xff09;&#xff0c;这两种方法正在重新定义大模…...

claude3.7高阶玩法,生成系统架构图,国内直接使用

文章目录 零、前言一、操作指南操作指导 二、提示词模板三、实战图书管理系统通过4o模型生成系统描述通过claude3.7生成系统架构图svg代码转换成图片 在线考试系统通过4o模型生成系统描述通过claude3.7生成系统架构图svg代码转换成图片 四、感受 零、前言 现在很多AI大模型可以…...