C++基础知识(六:继承)

首先我们应该知道C++的三大特性就是封装、继承和多态。

此篇文章将详细的讲解继承的作用和使用方法。

  • 继承

一个类,继承另一个已有的类,创建的过程

父类(基类)派生出子类(派生类)的过程

继承提高了代码的复用性

【1】继承的格式

class 类名:父类名
{};

【2】继承的权限

class 类名:继承的权限 父类名
{};如果不写继承方式,默认是私有继承
父类中的权限      public|private|protected  public|private|protected   public|private|protected              
继承方式                 public                    private                   protected
子类中的权限      public|不能访问|protected  private|不能访问|private    protected|不能访问|protected

【3】继承时类中的特殊成员函数

特殊的成员函数不会被继承

构造函数:

  • 需要在子类中显性调用父类的构造函数(初始化列表中)(透传构造)
  • 透传构造
  • 继承构造
  • 委托构造

需要在子类中显性调用父类构造函数的场合:

父类中只有有参构造  ----->子类在创建类对象时,必须手动调用父类的构造函数

#include <iostream>using namespace std;class Father
{
public:int age;char c;Father(int a,char c):age(a),c(c){cout << "Father有参" << endl;}
};class Child:public Father    //----->私有继承
{int high;
public:void show(){
        cout << c << endl;}
};int main()
{//Child c1;  //error,因为父类只有有参构造,而子类中没有提供能够调用父类有参构造的构造函数,不能成功创建父类的空间//Father f1;
    c1.age;
    cout << sizeof (Father) << endl;
    cout << sizeof (Child) << endl;return 0;
}

i)透传构造

在子类构造函数的初始化列表中,显性调用父类的构造函数

ii)继承构造

C++支持

不用在子类中再写一遍父类的构造函数

使用:using Father::Father; ----->在子类中使用父类的构造函数

直接使用继承构造的方式,不能对子类成员初始化

继承构造本质上并不是把父类中的构造函数继承给子类,编译器自动根据父类中构造函数的格式,提供出派生的构造函数(个数和参数都和父类中的构造函数一致),主要还是通过透传构造创建父类的空间

#include <iostream>
using namespace std;class Father
{
public:int age;char c;
//    Father(){cout << "Father无参" << endl;}Father(int a,char c):age(a),c(c){cout << "Father有参两个参数" << endl;}Father(char c):c(c){cout << "Father有参一个参数的" << endl;}Father(Father &other):age(other.age),c(other.c){cout << "Father拷贝" << endl;}
};class Child:public Father    //----->私有继承
{
private:int high;//父类中的public成员age,通过公有继承,仍然是publicusing Father::age;   //把父类中公有继承下来的age成员,在子类中改成私有权限
public:void show(){
        cout << c << endl;}//子类的无参构造,但是显性调用父类的有参构造还给了默认值//透传构造
//    Child():Father(12,'a'){cout << "Child无参构造" << endl;}
//    Child(int a,char c,int h):Father(a,c),high(h)
//    {cout << "Child有参构造" << endl;}//父类中的所有构造函数,都被继承到了子类中using Father::Father;   //更高效一些
};int main()
{
    Child c1(10);
    Child c2(20,'z');
    Child c3 = c2;//Father f1;//c1.age;
    cout << sizeof (Father) << endl;
    cout << sizeof (Child) << endl;return 0;
}

iii)委托构造

一个类的情况,并不直接通过无参构造实例化对象,而是无参构造委托了有参构造,实例化对象

继承时的情况

    Child():Child(10){cout << "Child无参构造" << endl;}   //Child c1
    Child(int a):Father(12,'a'),high(a)
    {cout << "Child有参构造一个参数" << endl;}

iv)拷贝构造

需要在初始化列表中显性调用父类的拷贝构造,传other对象到父类的拷贝构造中

Father(Father &other):age(other.age),c(other.c){cout << "Father的拷贝构造" << endl;}
Child(Child &other):Father(other),high(other.high){}

【4】继承时构造和析构的时机

继承关系,可以理解为包含关系

子类在继承父类时,会把父类中的成员保留一份,再来创建子类自己的成员

父类先构造,子类后构造

子类先析构,父类后析构

#include <iostream>using namespace std;
class F
{int *p;
public:F():p(new int){cout << "F无参构造" << endl;}~F(){delete p;
        cout << "F析构函数" << endl;}
};
class C:public F
{int *p;
public:C():p(new int){cout << "C无参构造" << endl;}~C(){delete p;
        cout << "C析构函数" << endl;}
};int main()
{
    C *p1 = new C;delete p1;   //空间释放时,会自动调用析构函数,无需手动调用
    p1 = nullptr;return 0;
}

【5】父子类中存在同名成员问题

访问时不会发生冲突,默认访问子类的

#include <iostream>
using namespace std;
class F
{
public:int *p;F():p(new int){cout << "F无参构造" << endl;}~F(){delete p;
        cout << "F析构函数" << endl;}
};
class C:public F
{
public:int *p;C():p(new int){cout << "C无参构造" << endl;}~C(){delete p;
        cout << "C析构函数" << endl;}
};int main()
{
    C *p1 = new C;*(p1->p) = 90;
    cout << *(p1->p) << endl;   //子类成员和父类成员同名,默认优先访问子类成员
    cout << *(p1->F::p) << endl;  //通过域限定符访问父类的成员delete p1;   //空间释放时,会自动调用析构函数,无需手动调用
    p1 = nullptr;return 0;
}
  • 多重继承

一个子类,继承自多个基类

【1】格式

class 类名:继承权限 父类名,继承权限 父类名····
{}

【2】当多个父类中包含同名成员

多个父类中包含同名成员,通过域限定符访问指定的父类中成员

#include <iostream>using namespace std;class Room
{
public:void clean(){
        cout << "打扫房间" << endl;}
};
class BedRoom
{
public:void play(){
        cout << "可以玩游戏" << endl;}void clean(){
        cout << "打扫卧室" << endl;}
};//Home类公共继承字Room和BedRoom类
class Home:public Room,public BedRoom
{
};int main()
{
    Home h1;
    h1.play();
    h1.Room::clean();
    h1.BedRoom::clean();return 0;
}
  • 菱形继承(钻石继承)

【1】格式

     A                ----->公共基类/   \
  B     C             ------>中间子类
   \   /
     D                ------>汇集子类

汇集子类中,会包含两份公共基类中的内容

【2】菱形继承存在的问题

  1. 会发生二义性的问题(同一个变量或者函数,可以通过两种方法访问)
  2. 如果公共基类,过大,会造成汇集子类中的代码膨胀/冗余
#include <iostream>using namespace std;
class A
{
public:int a;//A(int a):a(a){cout << "A" << endl;}
};class B:public A
{
public:int c;//B(int a,int c):A(a),c(c){cout << "B" << endl;}
};class C:public A
{
public://C(int a):A(a){cout << "C" << endl;}
};class D:public C,public B
{
public://D(int a,int c):B(a,c),C(a),A(a){cout << "D" << endl;}
};int main()
{
    D d1;
    d1.B::= 90;   //二义性,还可以直接通过中间子类访问,直接访问B中的a成员//cout << d1.C::A::a << endl;  //会发生二义性,因为访问A,但是有两条路径都访问到Areturn 0;
}

【3】虚继承(virtual)

虚继承指对公共基类的虚继承。

主要用于解决菱形继承问题,

采用虚继承后,公共基类中的内容,只会在汇集子类中存在一份,在汇集子类中,可以通过任意一条路径访问到公共基类中的成员

#include <iostream>using namespace std;
class A
{
public:int a;
};class B:virtual public A
{
public:int c;
};class C:virtual public A
{};class D:public B,public C
{};int main()
{
    D d1;
    d1.B::A::= 90;
    cout << d1.C::A::<< endl;return 0;
}

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

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

相关文章

SpringMVC 学习(三)之 @RequestMapping 注解

目录 1 RequestMapping 注解介绍 2 RequestMapping 注解的位置 3 RequestMapping 注解的 value 属性 4 RequestMapping 注解的 method 属性 5 RequestMapping 注解的 params 属性&#xff08;了解&#xff09; 6 RequestMapping 注解的 headers 属性&#xff08;了解&…

Linux安装jdk、tomcat、MySQL离线安装与启动

一、JDK和Tomcat的安装 1.JDK安装 直接上传到Linux服务器的&#xff0c;上传jdk、tomcat安装包 解压JDK安装包 //解压jdk tar -zxvf jdk-8u151-linux-x64.tar.gz 置环境变量(JAVA_HOME和PATH) vim /etc/profile 在文件末尾添加以下内容&#xff1a; //java environment expo…

osg qt5.15 osg3.6.3 osgEarth3.1 编译爬山

Demo演示&#xff1a;Qt5.15.2OSG3.6.3OsgEarth3.1的QtCreator下的msvc2019x64版本 osgQt编译 步骤一&#xff1a;下载解压 步骤二&#xff1a;CMake配置 步骤三&#xff1a;CMake配置添加osg环境 步骤四&#xff1a;CMake配置添加Qt环境 步骤五&#xff1a;CMake修改CMakeLis…

R语言入门笔记2.6

描述统计 分类数据与顺序数据的图表展示 为了下面代码便于看出颜色参数所对应的值&#xff0c;在这里先集中介绍&#xff0c; col1是黑色&#xff0c;2是粉红&#xff0c;3是绿色&#xff0c;4是天蓝&#xff0c;5是浅蓝&#xff0c;6是紫红&#xff0c;7是黄色&#xff0c;…

Android studio 下的APK打包失败问题解决办法

嗨&#xff0c;各位小伙伴们&#xff0c;我是你们的好朋友咕噜铁蛋&#xff01;作为移动应用开发者&#xff0c;在使用Android Studio进行APK打包时&#xff0c;有时候可能会遇到各种问题导致打包失败&#xff0c;这给我们的开发工作带来了一定的挑战。今天&#xff0c;我将和大…

欧瑞康真空泵650S干泵SV630罗茨泵WAU251-2001安装调试使用说明

欧瑞康真空泵650S干泵SV630罗茨泵WAU251-2001安装调试使用说明

mysql和sql server 中如何创建和管理用户

阅读本文之前请参阅----MySQL 数据库安装教程详解&#xff08;linux系统和windows系统&#xff09; 在MySQL和SQL Server中创建和管理用户的过程有所不同。下面分别介绍这两种数据库系统中用户管理的常见步骤。 MySQL 创建用户 在MySQL中创建用户的语法通常如下…

杰理701N可视化SDK之LED的配置和代码浅析

杰理701N可视化SDK LED的配置 LED硬件配置LED状态配置LED状态情景配置LED在SDK中相关代码 杰理可视化工具中可以配置LED的硬件配置和LED状态配置, 在可视化工具中的LED配置选项中设置 LED硬件配置 硬件配置可设置LED名, 推LED使用的IO口以及LED的点亮方式 SDK发布的标准原理…

02|Using filesort文件排序原理详解

文件排序方式 ● 单路排序&#xff1a;是一次性取出满足条件行的所有字段&#xff0c;然后在sort buffer中进行排序&#xff1b;用trace工具可以看到sort_mode信息里显示< sort_key, additional_fields >或者< sort_key, packed_additional_fields > ● 双路排序&a…

MySQL知识点总结(五)——锁

MySQL知识点总结&#xff08;五&#xff09;——锁 锁分类表锁 & 行锁如何添加表锁&#xff1f;如何添加行锁&#xff1f; 读锁 & 写锁行锁 & 间隙锁&#xff08;gap lock&#xff09;& 临键锁&#xff08;next-key lock&#xff09; 加锁机制分析可重复读隔离…

MATLAB:数组与矩阵

2.1 数组运算 数组运算时MATLAB计算的基础。由于MATLAB面向对象的特性&#xff0c;这种数值数组称为MATLAN最重要的一种内建数据类型&#xff0c;而数组运算就是定义这种数据结果的方法。 2.1.1 数组的创建和操作 在MATLAB中一般使用方括号“[]”、逗号“,”、空格和分号“;…

数据结构与算法相关题解20240225

数据结构与算法相关题解20240225 一、58. 最后一个单词的长度二、48. 旋转图像三、69. x 的平方根四、50. Pow(x, n) 一、58. 最后一个单词的长度 简单 给你一个字符串 s&#xff0c;由若干单词组成&#xff0c;单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度…

445. 两数相加 II(Java)

目录 题目描述&#xff1a;输入&#xff1a;输出&#xff1a;代码实现&#xff1a; 题目描述&#xff1a; 给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。 你可以假设除了数字 0 之外&am…

CSP-202209-3-防疫大数据

CSP-202209-3-防疫大数据 解题思路 一、数据结构定义 对于大模拟的题&#xff0c;合适的数据结构选择十分重要&#xff0c;正确的数据结构选择能够有效的提升解题效率 // 漫游消息结构体 struct RoamingData {int date, user, region; };vector<RoamingData> roamin…

汇编反外挂

在软件保护领域&#xff0c;尤其是游戏保护中&#xff0c;反外挂是一个重要的议题。外挂通常指的是一种第三方软件&#xff0c;它可以修改游戏数据、操作游戏内存或提供其他作弊功能&#xff0c;从而给玩家带来不公平的优势。为了打击外挂&#xff0c;游戏开发者会采取一系列措…

web安全学习笔记【16】——信息打点(6)

信息打点-语言框架&开发组件&FastJson&Shiro&Log4j&SpringBoot等[1] #知识点&#xff1a; 1、业务资产-应用类型分类 2、Web单域名获取-接口查询 3、Web子域名获取-解析枚举 4、Web架构资产-平台指纹识别 ------------------------------------ 1、开源-C…

代码随想录算法训练营第二十四天补|● 回溯理论基础 ● 77. 组合

回溯理论基础、组合问题 回溯理论基础 回溯能解决的问题 回溯的本质是穷举&#xff0c;穷举所有可能&#xff0c;然后选出我们想要的答案 回溯如何穷举&#xff1a; 横向遍历for循环&#xff0c;纵向遍历backtracking&#xff08;递归&#xff09;&#xff0c;一般来说&#…

pikachu靶场-RCE

介绍&#xff1a; RCE(remote command/code execute)概述 RCE漏洞&#xff0c;可以让攻击者直接向后台服务器远程注入操作系统命令或者代码&#xff0c;从而控制后台系统。 远程系统命令执行 一般出现这种漏洞&#xff0c;是因为应用系统从设计上需要给用户提供指定的远程命…

【数据结构】排序

目录 1.排序的概念及其应用 1.1排序的概念 1.2排序的应用 1.3常见的排序算法 2.常见排序算法的实现 2.1插入排序的实现 2.11基本思想 2.12直接插入排序 2.2希尔排序&#xff08;缩小增量排序&#xff09; 2.21基本思想 2.22希尔排序 2.3选择排序 2.31基本思想 2.3…

蓝桥杯《数字三角形》

题目描述 上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径&#xff0c;把路径上面的数加起来可以得到一个和&#xff0c;你的任务就是找到最大的和。 路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右边的那个数。此外&…