C++:组合和继承的区别

组合介绍以及与继承对比

什么是组合
(1)composition,组合,就是在一个class内使用其他多个class的对象作为成员
(2)用class tree做案例讲解
(3)组合也是一种代码复用方法,本质也是结构体包含

#include <iostream>
#include <vector>
#include <string>// Leaf 类
class Leaf {
public:Leaf(const std::string& color) : color_(color) {std::cout << "Leaf constructor called: " << color_ << std::endl;}~Leaf() {std::cout << "Leaf destructor called: " << color_ << std::endl;}void display() const {std::cout << "Leaf color: " << color_ << std::endl;}private:std::string color_;
};// Branch 类
class Branch {
public:Branch(int length) : length_(length) {std::cout << "Branch constructor called: " << length_ << " cm" << std::endl;}~Branch() {std::cout << "Branch destructor called: " << length_ << " cm" << std::endl;}void display() const {std::cout << "Branch length: " << length_ << " cm" << std::endl;}private:int length_;
};// Tree 类,包含 Leaf 和 Branch 对象
class Tree {
public:Tree(const std::string& leafColor, int branchLength) : leaf_(leafColor), branch_(branchLength) {std::cout << "Tree constructor called" << std::endl;}~Tree() {std::cout << "Tree destructor called" << std::endl;}void display() const {leaf_.display();branch_.display();}private:Leaf leaf_;Branch branch_;
};int main() {Tree tree("Green", 150);tree.display();return 0;
}

在这里插入图片描述

继承与组合的特点对比
(1)继承是a kind of(is a)关系,具有传递性,不具有对称性。
(2)组合是a part of(has a)的关系,
(3)继承是白盒复用。因为类继承允许我们根据自己的实现来覆盖重写父类的实现细节,父类的实现对于子类是可见的。
(4)继承的白盒复用特点,一定程度上破坏了类的封装特性,因为这会将父类的实现细节暴露给子类
(5)组合属于黑盒复用。被包含对象的内部细节对外是不可见的,所以它的封装性相对较好,实现上相互依赖比较小
(6)组合中被包含类会随着包含类创建而创建,消亡而消亡。组合属于黑盒复用,并且可以通过获取其它具有相同类型的对象引用或指针,在运行期间动态的定义组合。而缺点就是致使系统中的对象过多。
(7)OO设计原则是优先组合,而后继承

多继承及其二义性问题

多继承
(1)多继承就是一个子类有多个父类
(2)多继承演示
(3)多继承和单继承的原理,效果并无明显区别
(4)多继承会导致二义性问题
多继承的二义性问题1
(1)场景:C多继承自A和B,则C中调用A和B的同名成员时会有二义性
(2)原因:C从A和B各自继承了一个同名(不同namespace域)成员,所以用C的对象来调用时编译器无法确定我们想调用的是哪一个
(3)解决办法1:避免出现,让A和B的public成员命名不要重复冲突。但这个有时不可控。
(4)解决办法2:编码时明确指定要调用哪一个,用c.A::func()明确指定调用的是class A的func而不是class B的
(5)解决办法3:在C中重定义func,则调用时会调用C中的func,A和B中的都被隐藏了
(6)总结:能解决,但是都没有很好的解决。

多继承的二义性问题2
(1)场景:菱形继承问题。即A为祖类,B1:A, B2:A, C:B1,B2,此时用C的对象调用A中的某个方法时会有二义性
(2)分析:c.func()有二义性,c.A::func()也有二义性,但是c.B1::func()和c.B2::func()却没有二义性
(3)解决办法:和问题1中的一样,但是问题2更隐蔽,也更难以避免

在这里插入图片描述

// 祖类
class Aa {public:void show() { std::cout << "A's method" << std::endl; }
};// 派生类 B1 和 B2,从 A 继承
class B1 : public Aa {public:void show() { std::cout << "B1's show" << std::endl; }void showB1() { std::cout << "B1's method" << std::endl; }
};class B2 : public Aa {public:void show() { std::cout << "B2's show" << std::endl; }void showB2() { std::cout << "B2's method" << std::endl; }
};// 派生类 C,从 B1 和 B2 继承
class C : public B1, public B2 {public:void showC() { std::cout << "C's method" << std::endl; }
};int test070103() {C c;// c.Aa::show();    // 调用 A 的方法 不可以c.Aa::B1::show();  // 调用 A 的方法 不可以c.B2::Aa::show();  // 调用 A 的方法 不可以c.B1::show();      // 调用 B1 的方法c.B2::show();      // 调用 B2 的方法c.showB1();        // 调用 B1 的方法c.showB2();        // 调用 B2 的方法c.showC();         // 调用 C 的方法return 0;
}

虚继承解决菱形继承的二义性问题

虚继承怎么用
(1)场景:菱形继承导致二义性问题,本质上是在孙子类C中有B1和B2中包含的2份A对象,所以有了二义性。
(2)虚继承解决方案:让B1和B2虚继承A,C再正常多继承B1和B2即可
(3)虚继承就这么简单,就是为了解决菱形继承的二义性问题而生,和虚函数(为了实现多态特性)并没有直接关系

虚继承的实现原理
(1)虚继承的原理是:虚基类表指针vbptr和虚基类表virtual table
(2)参考:https://blog.csdn.net/xiejingfa/article/details/48028491

在这里插入图片描述

总结

理解什么是组合,一个class类里面有很多其他class类类型的成员变量
理解组合和继承的区别
二义性:执行了一个函数,确不一定是自己想指定的那个
解决方案:用c.A::func()明确的指定调用的是class
虚继承有点像条件编译,引入一次就好,不用重复引入,也能达到引入效果

学习记录,侵权联系删除。
来源:朱老师物联网大课堂

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

曹操的五色棋布阵 - 工厂方法模式

定场诗 “兵无常势&#xff0c;水无常形&#xff0c;能因敌变化而取胜者&#xff0c;谓之神。” 在三国的战场上&#xff0c;兵法如棋&#xff0c;布阵如画。曹操的五色棋布阵&#xff0c;不正是今日软件设计中工厂方法模式的绝妙写照吗&#xff1f;让我们从这个神奇的布阵之…

srs直播内网拉流带宽飙升问题记录

问题背景 srs部署在云服务器上&#xff0c;32核cpu&#xff0c;64G内存&#xff0c;带宽300M. 客户端从srs拉流&#xff0c;发现外网客户端拉流&#xff0c;cpu和带宽都正常。然而内网客户端拉流&#xff0c;拉流人数超过5人以上&#xff0c;带宽就会迅速飙升。 排查 用srs…

【爬虫】爬虫基础

目录 一、Http响应与请求1、Http请求2、Http响应3、状态码 二、Requests库1、发起GET请求2、发起POST请求3、处理请求头 三、BeautifulSoup库1、解析HTML文档2、查找和提取数据Ⅰ、查找单个元素Ⅱ、查找所有元素Ⅲ、使用CSS选择器Ⅳ、获取元素属性 四、爬取豆瓣电影榜 一、Http…

Desktop docker 部署 WordPress

Desktop Docker 部署 WordPress 之前都是在Linux里面玩的&#xff0c;今天看到别人在windwos下安装docker&#xff0c;一时兴起装了一个试试&#xff0c;效果一般&#xff0c;很吃硬盘空间和内存。 首先在docker官方下载桌面版&#xff0c;安装下一步一直到完成。 安装完docke…

一招杜绝 | 网站被劫持强制植入广告的问题

在我们日常上网过程中&#xff0c;经常会遇到打开一个网页&#xff0c;网页都还没有显示出来&#xff0c;一堆广告就弹出来的现象。或者网页刚刚打开&#xff0c;没几分钟 就会弹出来某游戏广告&#xff0c;注册领豪华坐骑等等的小广告。这些广告不仅仅会让我们对网站的真实性产…

强烈推荐!!李沐老师《动手学深度学习》最新Pytorch版!

动手学深度学习(PyTorch版)》是由李沐、Aston Zhang和孔德威共同编写的教材&#xff0c;专为深度学习初学者和实践者设计。本书使用PyTorch作为主要的深度学习框架&#xff0c;全面系统地介绍了深度学习的基本理论、常见模型和实际应用技巧。 书中内容包括深度学习的基础知识、…

逻辑回归(纯理论)

1.什么是逻辑回归&#xff1f; 逻辑回归是一种常用的统计学习方法&#xff0c;主要用于解决分类问题。尽管名字中包含"回归"&#xff0c;但它实际上是一种分类算法 2.为什么机器学习需要使用逻辑回归 1.二元分类 这是逻辑回归最基本和常见的用途。它可以预测某个事…

短视频矩阵:批量发布的秘密揭秘

在数字化时代&#xff0c;短视频已经成为一种广受欢迎的媒体形式。无论是用于品牌推广、产品营销还是个人创作&#xff0c;短视频都提供了一种直观、生动的方式来吸引观众的注意力。然而&#xff0c;有效地制作、管理和发布短视频对于许多创作者和企业来说是一个挑战。 为此&am…

unity3d:Shader知识点,矩阵,函数,坐标转换,Tags,半透明,阴影,深度,亮度,优化

基本结构 Shader "MyShaderName" {Properties {// 属性}SubShader {// 针对显卡A的SubShaderPass {// 设置渲染状态和标签Tags { "LightMode""ForwardBase" }// 开始Cg代码片段CGPROGRAM// 该代码片段的编译指令&#xff0c;例如&#xff1a;#p…

js vue table单元格合并

实现效果 关键代码 <table classtable table-bordered><thead><tr><th>检测项目</th><th>详细说明</th><th>检测结果</th><th>检测说明</th></tr></thead><tbody><tr ng-repeatrow in…

【记录】LaTex|LaTex调整算法、公式、表格内的字体大小(10种内置字号)

文章目录 【记录】LaTex&#xff5c;LaTex调整算法、公式、表格内的字体大小&#xff08;10种内置字号&#xff09;省流版1 字体大小2 测试代码 详细版1 \tiny2 \scriptsize3 \footnotesize4 \small5 \normalsize6 \large7 \Large8 \LARGE9 \huge10 \Huge 【记录】LaTex&#x…

【干货】一文带你看懂什么是渠道分销?如何管理渠道分销

在当今竞争激烈的市场环境中&#xff0c;企业想要扩大市场份额、提高产品或服务的可见度&#xff0c;有效的渠道分销策略是关键。 什么是渠道分销&#xff1f; 渠道分销&#xff0c;简而言之&#xff0c;是指企业利用中间商&#xff08;如经销商、代理商、零售商等&#xff0…

万字长文!流行 AI 视频生成大模型介绍 浅体验

目录 国外 AI 视频生成大模型Sora——值得期待的引领者官方描述拥有强大的能力一经发布&#xff0c;立即爆火不同业内人士的评价周鸿祎的评价陈楸帆的评价 值得期待的引领者 Dream Machine——宣传虽好&#xff0c;但仍需努力新兴的 AI 视频生成大模型媒体强烈的追捧实测体验&a…

PyTorch | 加速模型训练的妙招

引言 提升机器学习模型的训练速度是每位机器学习工程师的共同追求。训练速度的提升意味着实验周期的缩短&#xff0c;进而加速产品的迭代过程。同时&#xff0c;这也表示在进行单一模型训练时&#xff0c;所需的资源将会减少。简而言之&#xff0c;我们追求的是效率。 熟悉 PyT…

基于springboot+mybatis学生管理系统

基于springbootmybatis学生管理系统 简介&#xff1a; 题目虽然是学生管理系统&#xff0c;但功能包含(学生&#xff0c;教师&#xff0c;管理员),项目基于springboot2.1.x实现的管理系统。 编译环境 &#xff1a; jdk 1.8 mysql 5.5 tomcat 7 框架 &#xff1a; springboot…

UI设计工具选择指南:Sketch、XD、Figma、即时设计

在数字产品设计产业链中&#xff0c;UI设计师往往起着连接前后的作用。产品经理从一个“需求”开始&#xff0c;制定一个抽象的产品概念原型。UI设计师通过视觉呈现将抽象概念具体化&#xff0c;完成线框图交互逻辑视觉用户体验&#xff0c;最终输出高保真原型&#xff0c;并将…

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【HMAC(C/C++)】

HMAC(C/C) HMAC是密钥相关的哈希运算消息认证码&#xff08;Hash-based Message Authentication Code&#xff09;&#xff0c;是一种基于Hash函数和密钥进行消息认证的方法。 在CMake脚本中链接相关动态库 target_link_libraries(entry PUBLIC libhuks_ndk.z.so)开发步骤 生…

对接高德开放平台API

高德开放平台API&#xff1a; https://lbs.amap.com/ 一、天气查询 天气查询: https://lbs.amap.com/api/webservice/guide/api/weatherinfo adcode城市码表下载: https://lbs.amap.com/api/webservice/download Component public class WeatherUtil {Resourceprivate GdCon…

使用F1C200S从零制作掌机之USB游戏手柄

一、USB手柄 COIORVIS PC游戏手柄电脑USB FC模拟器经典游戏手柄 安卓手机有线连接单打格斗对打拳皇 经典有线手柄【黄色】 https://item.jd.com/10046453175183.html 插入USB即可自动识别。 # [ 1425.447643] usb 1-1: USB disconnect, device number 7 [ 1427.072155] usb …

43、nginx的优化、防盗链、重定向、代理

nginx的优化、防盗链、重定向、代理 一、nginx的优化 1.1、隐藏版本号 server_tokens off;隐藏版本号 [roottest1 conf]# vim nginx.confserver_tokens off;[roottest1 conf]# nginx -t nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok ngin…