[第五天】C++继承:单继承、多继承、菱形继承和虚继承的深度解析

一、单继承

1、概述

        C++最重要的特征是代码重用,通过继承机制可以利用已有的数据类型来定义新的数据类型,新的类不仅拥有旧类的成员,还拥有新定义的成员。

        例如一个B类继承于A类,或称从类A派生类B。这样的话,类A成为基类(父类),类B成为派生类(子类)。派生类中的成员,包含两大部分:一类是从基类继承过来的,一类是自己增加的成员。从基类继承过过来的表现其共性,而新增的成员体现了其个性。

 2、子类的定义形式

定义形式:

class 父类{};
class 子类:继承方式 父类名
{//新增子类数据
};

继承方式:private protected public(推荐) 

公共继承 保持不变,保护继承变保护,私有继承变私有,所有父类私有在子类中不可见。 

 以public为例:

3、子类的构造析够顺序

class Base
{
public:Base(){cout<<"父类构造函数"<<endl;}~Base(){cout<<"父类析构函数"<<endl;}
};
class Other
{
public:Other(){cout<<"Other构造函数"<<endl;}~Other(){cout<<"Other析构函数"<<endl;}
};
class Son :public Base
{
public:Other ob;
public:Son(){cout<<"子类构造函数"<<endl;}~Son(){cout<<"子类析构函数"<<endl;}
};
void test()
{Son ob;
}

 运行结果:

4、子类调用成员对象和父类的有参构造

一般情况下,子类 会自动调用 成员对象和父类的默认构造

调用成员对象和父类的有参构造:子类 必须使用有参构造初始化列表 

初始化列表时:父类类名称成员对象对象名

#include<iostream>
#include<string>
using namespace std;
class Base
{
public:int a;
public:Base(){cout << "父类默认构造函数" << endl;}Base(int a){this->a = a;cout << "父类有参构造函数" << endl;}~Base(){cout << "父类析构函数" << endl;}
};
class Other
{
public:int b;
public:Other(){cout << "Other默认构造函数" << endl;}Other(int b){this->b = b;cout << "Other有参构造函数" << endl;}~Other(){cout << "Other析构函数" << endl;}
};
class Son :public Base
{
public:int c;Other ob;
public:Son(){cout << "子类默认构造函数" << endl;}//子类要给成员中b赋值,父类中的a赋值//不能直接赋值,父类会先执行存在,调用父类默认构造Son(int a,int b,int c):Base(a),ob(b)//用初始化列表,父类写类名称 成员对象用对象名{this->c=c;cout << "子类有参构造函数" << endl;}~Son(){cout << "子类析构函数" << endl;}
};
void test()
{Son ob(10,20,30);
}
int main(int argc, char* argv[])
{test();return 0;
}

 5、子类和父类同名成员处理

处理方式:加作用域

1、子类和父类 同名成员数据

        默认优先访问 子类的同名成员,加父类作用域 访问父类的同名成员。

2、子类和父类 同名成员函数

 注:子类会重定义父类的同名函数:

重载:无继承,同一作用域,参数的个数、顺序、类型不同 都可重载

重定义:有继承, 子类 重定义 父类的同名函数(参数可以不同)(非虚函数)

        子类一旦 重定义了父类的同名函数(不管参数是否一致),子类中都将屏蔽父类所有的同名函数。必须加父类作用域 访问父类的同名成员。

class Base
{
public:void fun(){cout<<"父类fun函数"<<endl;}void fun(int a){cout<<"父类带一个参数fun函数"<<endl;}void fun(int a,int b){cout<<"父类带两个参数fun函数"<<endl;}
};
class Son :public Base
{
public:void fun(){cout<<"子类fun函数"<<endl;}
};
void test()
{Son ob;//类默认优先访问 子类的同名成员ob.fun();//必须加父类作用域 访问父类的同名成员ob.Base::fun(10);//OB.fun(10);会报错ob.Base::fun(10,20);
}

6、子类不能继承的父类成员

父类的构造析够重载赋值运算符operator= 不能被子类 继承。

二、多继承

1、多继承的格式

class 父类1{};
class 父类2{};class 子类:继承方式1 父类1, 继承方式2 父类2
{//新增子类数据
};

子类拥有父类1,父类2的大部分数据

2、多继承中同名成员 

 三、菱形继承

        两个派生类继承同一个基类而又有某个类同时继承者两个派生类,即有公共祖先的继承。这种继承被称为菱形继承,或者钻石型继承。

        最底层的子类 数据 会包含多份公共祖先的数据和基类派生的派生类的数据

         

 形象图:

问题: 

         1、羊继承了动物的数据和函数,鸵同样继承了动物的数据和函数,当草泥马调用函数或者数据时,就会产生二义性,通过加作用域解决。

        2、草泥马继承自动物的函数和数据继承了两份,其实我们应该清楚,这份数据我们只需要一份就可以,通过虚继承解决。

class Animal
{
public:int Data;
};
class Sheep:public Animal{};
class Tuo:public Animal{};
class SheepTuo:public Sheep,public Tuo{};void test()
{SheepTuo ob;//cout<<ob.Data;二义性报错cout<<ob.Sheep::Data<<endl;cout<<ob.Tuo::Data<<endl;
}

四、虚继承 

        虚继承 解决 菱形继承中 多份公共祖先数据的问题

1、虚继承的概述

        子类虚继承父类 子类只会保存一份公共数据。

        方式:在继承方式 前加virtual修饰

2、分析虚继承的实现原理(vs端) 

从电脑开始中的目录找找到 Developer Command Prompt for VS 2022 并打开

在vs复制完整路径后进入对应文件夹。

dir命令查看文件 

 

 导出单个类的布局:

cl /d1 reportSingleClassLayoutAnimal main.cpp

Sheep布局: 

Tuo布局:

SheepTuo布局:

         虚继承 会在子类中产生 虚基类指针(vbptr) 指向 虚基类表(vbtable), 虚基类表纪录的是 通过该指针访问公共祖先的数据的偏移量。

 注意:

1、虚继承只能解决具备公共祖先的多继承所带来的二义性问题,不能解决没有公共祖先的 多继承的

2、工程开发中真正意义上的多继承是几乎不被使用,因为多重继承带来的代码复杂性远多 于其带来的便利,多重继承对代码维护性上的影响是灾难性的,在设计方法上,任何多继承 都可以用单继承代替

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

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

相关文章

2月06日,每日信息差

第一、建业地产有40个项目入围“白名单”&#xff0c;项目分布在郑州、信阳、焦作、洛阳等城市。接近建业地产人士表示&#xff0c;因各城市项目申报、审批工作进度不同&#xff0c;各城市项目的“白名单”申报工作还在持续进行&#xff0c;相关审批通过后&#xff0c;公司入围…

零基础学Python之面向对象

1.面向对象编程简介 &#xff08;1&#xff09;什么是面向对象 面向对象程序设计(Object Oriented Programming)作为一种新方法&#xff0c;其本质是以建立模型体现出来的抽象思维过程和面向对象的方法。模型是用来反映现实世界中事物特征的。任何一个模型都不可能反映客观事…

StarRocks 1 月社区动态(2024)

StarRocks 在 2023 年不断进化&#xff0c;锤炼核心功能&#xff0c;打磨全新特性&#xff0c;成功实现了从全场景 OLAP 到云原生湖仓的全面升级&#xff0c;成为湖仓新范式的造浪者。2024 年&#xff0c;我们期待与您一同续写新篇章&#xff0c;共同迈向“极速统一”的新征程&…

使用#if 和 #endif 实现注释,及原因

注释我们代码中经常使用&#xff0c; 单行注释和多行注释我们都会经常用到。 但是有些场景下这两种注释并不是很方便&#xff0c;这样我们就可以使用上面的两个宏来对代码进行注释。 什么情况下使用那两种注释不方便? 1. 如果代码很多时&#xff0c;我们如果一行一行…

【Qt】常见问题

1.存在未解析的标识符 将build文件夹删掉重新编译。 2.左侧项目目录栏无法删除已添加项目 打开目标项目上一级的pro文件&#xff0c;将目标文件名字注释或者删除掉&#xff0c;最后保存&#xff0c;qt就会自动更新&#xff0c;将该项目隐藏掉。 3.在qt creator下添加槽函数…

c++运算符优先级

这里写目录标题 C运算符优先级定义了表达式中运算符的计算顺序。当一个表达式中有多个运算符时&#xff0c;运算符的优先级决定了哪些运算符先被计算。下面是C中一些常见运算符的优先级列表&#xff0c;从高到低排序&#xff1a; 阿里云参考链接&#xff1a;developer.aliyun.c…

模拟串口LV2,解决硬件串口资源不足问题!!!!

模拟串口通信 2.0 版本&#xff01;&#xff01; 我在前面的文章里面有写了 虚拟串口通信&#xff0c;虽然说能用&#xff0c;但是用过的小伙伴都说 “好!” 优缺点: 先说一点&#xff0c;2.0版本并不适用于同硬件串口的所有场合&#xff0c;仅仅针对自己开发的电子垃圾的主…

[office] 网优必备的10大经典函数公式! #知识分享#媒体

网优必备的10大经典函数公式! Excel软件看似简单&#xff0c;其实花样很多&#xff0c;尤其Excel表格。但其实只要用心多练&#xff0c;效率轻松提升个十倍百倍真不是问题!赶紧一起来get新技能吧~ ▋函数公式一 我们都知道从网管中查询出来的经纬度是没有小数点的。我看到不…

护眼灯色温多少合适?推荐五款合适色温的护眼台灯

很多人在购买台灯之后只会根据周围环境灯光的明暗调节亮度&#xff0c;对于色温的了解并不多&#xff0c;不知道色温应该调节到什么数值比较合适&#xff0c;有些人也根本没有意识到色温在影响人情绪方面起着重要作用&#xff0c;接下来就一起来看一下色温的标准。 一、什么色…

Day4.

单链表 #include <head.h>typedef struct List{int value;struct List *pointe; }*list; list create_space() {list s(struct List *)malloc(sizeof(struct List)); //向堆区申请空间s->pointe NULL;//初始化s->value 0;return s; } list inserhead_list(lis…

AI改编游戏大电影《使命召唤:幽灵重生》(下)

AI改编游戏大电影《使命召唤&#xff1a;幽灵重生》&#xff08;下&#xff09; 幽灵重生携生化武器毁灭人类&#xff0c;普莱斯上尉点上雪茄拿起武器&#xff0c;英雄再次迎来使命的召唤&#xff01; 《使命召唤&#xff1a;幽灵重生》&#xff08;下&#xff09;&#xff1a…

电力负荷预测 | 基于TCN的电力负荷预测(Python)———结果比对

文章目录 效果一览文章概述源码设计参考资料效果一览 文章概述 电力负荷预测 | 基于TCN的电力负荷预测(Python)———结果比对 python3.8 keras2.6.0 matplotlib3.5.2 numpy1.19.4 pandas1.4.3 tensorflow==2.6.0

【宝藏系列】嵌入式入门概念大全

【宝藏系列】嵌入式入门概念大全 0️⃣1️⃣操作系统&#xff08;Operating System&#xff0c;OS&#xff09; 是管理计算机硬件与软件资源的系统软件&#xff0c;同时也是计算机系统的内核与基石。操作系统需要处理管理与配置内存、决定系统资源供需的优先次序、控制输入与输…

jquery写表格,通过后端传值,并合并单元格

<!DOCTYPE html> <html> <head><title>Table Using jQuery</title><style>#tableWrapper {width: 100%;height: 200px; /* 设置表格容器的高度 */overflow: auto; /* 添加滚动条 */margin-top: -10px; /* 负的外边距值&#xff0c;根据实际…

Days 20 ElfBoard 板 FFmpeg移植

FFmpeg是一套可以用来记录、转换数字音频、视频&#xff0c;并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。因此&#xff0c;对于从事多媒体技术开发的工程师来说&#xff0c;深入研究FFMPEG成为一门必不可少的工作…

C++ 11新特性之tuple

概述 在C编程语言的发展历程中&#xff0c;C 11标准引入了许多开创性的新特性&#xff0c;极大地提升了开发效率与代码质量。其中&#xff0c;tuple&#xff08;元组&#xff09;作为一种强大的容器类型&#xff0c;为处理多个不同类型的值提供了便捷的手段。tuple是一种固定大…

NLP_神经概率语言模型(NPLM)

文章目录 NPLM的起源NPLM的实现1.构建实验语料库2.生成NPLM训练数据3.定义NPLM4.实例化NPLM5.训练NPLM6.用NPLM预测新词 NPLM小结 NPLM的起源 在NPLM之前&#xff0c;传统的语言模型主要依赖于最基本的N-Gram技术&#xff0c;通过统计词汇的共现频率来计算词汇组合的概率。然而…

解决opencv在图片中添加中文字体乱码问题

解决opencv在图片中添加中文字体乱码问题 需要事先安装PIL库 from PIL import Image, ImageDraw, ImageFont import cv2def cv2_img_add_text(img, text_str, left, top, text_color, text_size): if isinstance(img, np.ndarray):img Image.fromarray(cv2.cvtColor(img, …

【自然语言处理】微调 Fine-Tuning 各种经典方法的概念汇总

【自然语言处理】微调 Fine-Tuning 各种经典方法的概念汇总 前言请看此微调 Fine-TuningSFT 监督微调&#xff08;Supervised Fine-Tuning&#xff09;概念&#xff1a;监督学习&#xff0c;无监督学习&#xff0c;自监督学习&#xff0c;半监督学习&#xff0c;强化学习的区别…

Jetpack之RadionBtton、Switch、Checkbox组件介绍

Jetpack Compose系列(9) - RadionBtton、Switch、Checkbox组件介绍 RadioButton 跟View体系一样&#xff0c;Compose也有RadioButton单选按钮组件&#xff0c;遵从Material Design风格。 其构造函数如下&#xff1a; Composable fun RadioButton(selected: Boolean,onClick…