C++继承总结

2023-05-16

继承的概念
继承机制是面向对象程序设计使代码可以复用的重要手段,它允许程序员在保持原有类特性的基础之上进行其他扩展,增加功能,这样产生的新类,称之为派生类。
继承呈现了面向对象程序设计的层次结构,体现了有简单到复杂的认知过程。

class Person{
public:
    void Print(){
        cout << "name" << _name << endl;
        cout << "age" << _age << endl;
    }
protected:
    string _name = "kaiser";
    int _age = 21;        
}

//继承父类Person的成员(包括函数和变量),都变成了子类Student的一部分,并且子类还有自己新增加的变量或者函数
class Student : public Person{
protected:
    int _stdid;//学号
}

在这里插入图片描述
三种继承方式的区别
在这里插入图片描述

**1.**基类的私有成员在派生类中,不可访问,但是基类的私有成员是派生类的一部分。所以在继承的部分,很少在基类中定义私有成员。

**2.**基类的保护成员在派生类中可见,但是其他类外的地方不可见。

**3.**无论哪一种继承方式,都不会影响基类的正常使用。

**4.**如果继承方式没写,那么class的默认继承方式是private继承,struct的默认继承方式是public继承

切片操作

派生类对象、指针、引用可以直接赋值给基类对象、指针。引用

Person p;
Student s;

p = s;
Person& p1 = s;
Person* p2 = &s; 

注意:
**1.**基类对象不能赋值给派生类对象
**2.**基类指针、引用可以用强制类型转换赋值给派生类指针、引用(但是存在不安全情况,要看赋值的基类的指针、引用的具体指向是否是派生类)

下图中红色是强制转换不安全情况
绿色是强制转换安全情况
蓝色是切片操作
在这里插入图片描述
同名隐藏

class Person{
protected:
    int num;
    int id = 1;
}
class Student : public Person{
public:
    void setNum(int num){
        num = num;
    }
    void setNum2(int num){
        this -> num = num;
    }
    void showId(){
        cout << id << endl;
    }
    
protected:
    int num;
    int id = 100;
}
  1. 上方代码中setNum函数中num是一个局部变量,并不是Student类中的成员变量num,所以调用setNum函数不影响成员变量num的值;setNum2函数才有改变成员变量num效果;
  2. Person和Stdent的id成员变量是两个不同的变量,调用showId函数,打印结果是100。

小结:
3. 同名隐藏发生在不同作用域下,同作用域下叫函数重载;
4. 父类和子类中有同名的成员,子类只能看到自己的成员,如果需要访问父类的成员,需要加上父类的作用域;
5. 成员变量隐藏:成员变量名相同;
6. 函数名相同,父类子类作用域不同构成函数隐藏,与参数个数无关;
7. 只要不同作用域下,有同名成员,当前作用域下的这个名称的成员就会覆盖其他同名成员,该机制不是继承独有的。

继承中的成员函数
子类的构造函数

  1. 一定会调用父类的构造函数
    a. 如果不显式调用,自动调用父类的默认构造;
    b. 如果显式调用,则调用显式指定的父类构造;
  2. 继承自父类的成员变量,一定要通过父类的构造函数完成初始化,在子类的初始化列表中只能显式初始化子类新增的成员变量;
  3. 初始化顺序:一定是先初始化父类的成员,再初始化子类的成员;
  4. 创建子类对象时,首先调用子类的构造函数,在子类构造函数的初始化列表中调用父类的构造函数,先执行父类的构造逻辑,再执行子类的构造逻辑;

子类的拷贝构造函数

  1. 默认行为(没有显式定义子类的拷贝构造):调用父类的拷贝构造;
  2. 显式定义子类的拷贝构造的默认行为(没有显式调用父类的拷贝构造):调用父类的默认构造;
  3. 在子类的拷贝构造中可以指定调用哪一个父类的构造函数,可以是拷贝构造函数,也可以是其他构造函数;

子类的赋值运算符重载函数

  1. 默认行为:调用父类的赋值运算符重载函数;
  2. 显示定义:和父类的赋值运算符构成同名隐藏;
  3. 建议调用父类的赋值运算符,可以使代码复用;

子类的析构函数
1.编译器自动生成的析构函数自动调用父类析构函数;
2.显式定义的子类析构函数自动调用父类析构函数;
3.无论子类析构函数是否显式调用父类析构函数,编译器都会自动调用一次父类的析构函数;
4.子类析构函数和父类析构函数底层函数名相同,构成函数隐藏;
注意:父类析构函数不需要在子类中显式调用,防止资源二次释放问题。

友元关系不能继承
基类静态成员无论经过多少次继承,都只有一个实例对象

菱形继承问题
在这里插入图片描述
菱形继承存在数据冗余和二义性的问题,如上图,Assistant类中有Person类成员两份

解决方法:以上图为例,让Student和Teacher虚拟继承Person,class Student : virtual public Person,class Teacher : virtual public Person。这样的话Assistant中就只有一份Person类的成员了

虚基表和虚基表指针

class A{
public:
    int a;
}
class B:virtual public A{
public:
    int b;
}
class C:virtual public A{
public:
    int c;
}
class D:public B, public C{
public:
    int d;
}            

在这里插入图片描述

在虚拟继承中,存在虚基表指针和和虚基表,虚基表指针指向虚基表的首地址,虚基表中存放虚基表指针的地址到公共成员的偏移量。
通过用指针的大小换取重复成员的大小,重复的成员越多,越能看出虚拟继承的好处。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++继承总结 的相关文章

随机推荐

  • 4年产品点滴心路——谈谈形而上的3个产品素质

    我是一名互联网产品人员 xff0c 曾供职过多家互联网公司 xff0c 包括一些员工数千的老牌龙头企业和一些初创公司 排除老生常谈的产品技能以及方法论 xff0c 我最近对一些大型企业初创项目 新型领域创业公司的产品人员的工作软实力有很大兴
  • 基于LMS8962的跑马灯教学程序——定时器、串口及GPIO的使用

    基于LMS8962的跑马灯教学程序 定时器 串口及GPIO的使用 一 电路原理图 从图中可知 xff0c 各LED是逢GPIO口为0 xff0c 即低电平时亮 xff0c 为1 xff0c 即高电平时灭 xff0c 呈反逻辑 由于四灯接至引
  • 四年产品点滴心路(二)——互联网公司的组织规模与产品特点浅析

    新年伊始 xff0c 让我们放慢脚步 xff0c 回溯互联网服务长河的源头 xff1a 计算机技术 2000年以来 xff0c 国内普通大学里 xff0c 一位只要对计算机 软件有兴趣并打算在此行业长远发展的大学生 xff0c 大都经历过在
  • 百川纳海,移动称雄——辽宁工程技术大学2011移动开发者大会见闻

    2011年11月3日 xff0c IT界翘首瞩目的2011中国北京移动开发者大会 xff08 MDCC xff09 在北京国家会议中心如期举行 本次MDCC由CSDN和创新工场联合主办 xff0c 以 移动大变局下的抉择 为标题 xff0c
  • 云之彼端,牵手未来—— “我思故我在”—我眼中的第四届中国云计算大会

    一 xff0e 满怀激动踏征程 第四届全国云计算大会初体验 2012年5月23日至25日 业界瞩目的第四届中国云计算大会 xff08 以下简称 大会 xff09 在京隆重举行 本次大会由国家发展和改革委员会 工业和信息化部 北京市人民政府及
  • 落花渐欲迷人眼,移动前景看用户

    火红的深秋10月 xff0c 万众瞩目的第三届中国移动开发者大会于19日在北京国家会议中心如期举行 本次大会邀请到了诸多互联网巨头公司中相关项目负责人及移动互联先驱精英 xff0c 百家争艳齐聚一堂 xff0c 共同探讨在移动互联网高速发展
  • 新员工总结

    感谢29 日下午张宁主编为我们移动频道新员工安排的培训 通过本次员工培训 xff0c 在工作目标和方向上有了较为清晰的认识 xff0c 主要总结如下 xff1a 1 明确移动频道工作重心 xff1a 移动 应用 开发 围绕这三点 xff0c
  • 微软Win8开发马拉松感悟

    前几天前往微软win8开发者马拉松大赛 xff0c 对于微软中国有了一些了解 xff0c 也有了一些体悟 xff0c 在这里稍微记录一下 首先一点就是微软对于开发者的态度 在会场看到了许多沙发和抱枕 xff0c 还有毛毯等 xff0c 另外
  • 基于prometheus的网络指标监控

    1 网络指标监控 网络设备 交换机 路由器 防火墙 本身并没有太多的监控方式 xff0c 常规的是使用snmp xff0c 通过oid去采集网络设备的指标 xff0c 例如 xff0c 流量或者错包 xff0c 不过近年来也出现了新的采集方
  • 【解决】UART问题

    UART和USART区别 UART xff08 Universal asynchronous receiver transmitter xff09 xff1a 通用异步收发器 USART xff08 Universal synchronou
  • 小白也能配置VScode的C/C++环境

    必要软件的下载 前往下方Github链接下载 xff0c 选择这里下载 下载地址 xff1a https github com SDchao AutoVsCEnv WPF releases latest 2022 9 25 更新 xff1a
  • 网络协议栈0:从一个例子开始

    最近因工作需要写一个网卡驱动 xff0c 晕倒 xff0c 没有任何网络知识 xff0c 就写网络驱动 xff01 可是 xff0c 为了五斗米糊口 xff0c 不得不从啊 于是 xff0c 打算从网络协议栈开始 xff0c 把网络搞一搞
  • Ubuntu 18.04 Intel RealSense D435i 相机标定教程

    1 D435i相机简介 RealSenseD435i 是一款立体视觉深度相机 xff0c 如下图所示 xff0c 其集成了两个红外传感器 xff08 IR Stereo Camera xff09 一个红外激光发射器 xff08 IR Pro
  • 使用IDEA创建Servlet项目

    使用 IDEA创建Servlet项目 原料 xff1a IDEA 2016 xff0c Tomcat8 0 步骤如下 xff1a 1 创建项目 File gt New gt Project gt Java Enterprise 如下图所示
  • px4基本知识

    1 PX4自驾仪 PX4是与平台无关的自动驾驶仪软件 xff08 或称为固件 xff09 xff0c 可以驱动无人机或无人车 它可以被烧写在某些硬件 xff08 如Pixhawk v2 xff09 xff0c 并与地面控制站在一起组成一个完
  • React尚硅谷115-126(setState、Hooks、Fragment、context、组件优化、renderprops、错误边界、组件通信方式总结)

    115 项目打包运行 npm install serve g serve build 116 setState setState是同步的 xff0c 但是引起页面更新动作是异步的 xff08 状态的更新是异步的 xff09 相当于this
  • 程序员跨越式成长指南

    我的 GitChat 达人课 程序员跨越式成长指南 xff0c 更新了三篇文章 xff0c 现在完成的内容如下 xff1a 导读 xff1a 开发路上的两次关键跨越 第01课 xff1a 如何做到选择大于努力 第02课 xff1a 开发者的
  • 树莓派一些传感器的使用

    树莓派一些传感器的使用 Part 1 树莓派GPIO编号方式和引脚说明 参考 xff1a 树莓派开发系列教程9 树莓派GPIO控制 1 功能物理引脚 从左到右 xff0c 从上到下 xff0c 左边基数 xff0c 右边偶数 xff0c 1
  • centos 安装Git-cola

    首先安装Git sudo yum y install git 找到 git all noarch 安装这个 sudo yum install git all noarch 61 61 61 61 61 61 61 61 61 61 61 6
  • C++继承总结

    继承的概念 继承机制是面向对象程序设计使代码可以复用的重要手段 xff0c 它允许程序员在保持原有类特性的基础之上进行其他扩展 xff0c 增加功能 xff0c 这样产生的新类 xff0c 称之为派生类 继承呈现了面向对象程序设计的层次结构