C++继承(一)

2023-10-27

目录

继承方式

继承同名成员处理方式(父类与子类中都有相同的成员)

继承同名静态成员处理方式

继承中的对象模型

继承中构造和析构函数

菱形继承

多继承语法


在多种接口需要相同输出时,C++的继承相对于传统方式更有利也更方便维护

C++继承语法:

class 子类:继承方式 父类;

传统方式:

class Java{
public:
  void header(){
    cout << "首页、公开课" << endl;
  }
  void footer(){
    cout << "帮助中心" << endl
  }
}

class Python{
  void header(){
    cout << "首页、公开课" << endl;
  }
  void footer(){
    cout << "帮助中心" << endl
  }
}

void test01(){
  cout << "Java下载视频页面如下" << endl;
  Java ja;
  ja.header();
  ja.footer();

  cout << "Python下载视频页面如下" << endl;
  Python py;
  py.header();
  py.footer();  
}



int main(){
  test01();
}

而使用C++继承会显得更加简洁,会让阅读代码的人更加轻松!

C++继承方式:

class BasePage{
public:
  void hearer(){
    cout << "首页、公开课、登陆 "<<end;
  }
  
  void footer(){
    cout << "帮助中心、交流合作" << endl;
  }
  void left(){
		cout << "Java、Python " << endl;
  }
}

class Java : public BasePage{
public:
  void content(){
		cout << "JAVA学科视频 " <<endl;
  }
}

class Python : public BasePage{
public:
  void content(){
    cout << "Python学科视 频 " << endl; 
  }
}

void test01(){
  cout << "JAVA下载视频页面如下:"  << endl;
  Java ja;
  ja.heater();
  ja.footer();
  
  Python py;
  py.heateer();
  py.footer();
}

int main(){
  test01();
  
  return 0;
}

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBARVVHT1VBTElDRQ==,size_12,color_FFFFFF,t_70,g_se,x_16

继承方式

C++的继承方式有三种:

public(公开)、protected(保护)、private(私密)

//继承方式

//公共继承
class Base1{
public:
  int m_A;
protected:
  int m_B;
private:
  int m_C;
};

class Son : public Base1{
public:
  void func(){
		m_A = 10;	//父类中的公共权限成员 到子类中依然是公共权限
    m_B = 10;	//父类中的包含权限成员 到子类中依然是保护权限
    m_C = 10;	//子类中的私有权限成员 子类访问不到
  }
};

void test01(){
  Son s1;
  s1.m_A = 100;
  s1.m_B = 100;	//到了son中 m_B是保护权限 类外访问不到
}

//保护继承
class Base2{
  public:
  int m_A;
protected:
  int m_B;
private:
  int m_C;
};

class Son2 : protected Base2{
public:
  void func(){
    m_A = 100;	//父类中公共成员 到子类中变为保护权限
    m_B = 100;	//父类中保护成员,到子类中变为保护权限
    //m_C = 100;	//父类中的私有成员 子类访问不到	
  }
}

void test02(){
  Son2 s1;
  s1.m_A = 100;	//在Son2中m_A变为保护权限,因此类外访问不到
  s1.m_B = 100;	//在Son2中m_B保护权限 不可以访问
}

//私有继承 
class Base3{
 public:
  int m_A;
protected:
  int m_B;
private:
  int m_C;
};

class Son3 : private Base3{
public:
  void func(){
    m_A = 100;	//父类中公共成员 到子类中变为了 私有成员
    m_B = 100;	//父类中保护成员 到子类中变为了 私有成员
    m_C = 100;	//父类中私有成员,子类访问不到
  }
};

class GrandSon3 : public Son3{		//到了son3中 m_A变为私有,即使是儿子 也访问不到
public:
  void func(){
    m_A = 1000;	
    m_B = 1000;
    
  }
}

void test03(){
  s1.m_A = 10000;	//到son3中 变为私有成员 类外访问不到	
  s1.m_B = 120000; //到son3中 变为私有成员 类外访问不到 
}

 总的来说:原本父类中就是private和protected的继承方式,到子类中也无法访问

而子类继承时,如果继承方式为private和protected的都会成为相应的权限类型,而更高的权限则不会变动,如:原本是public方式,但是其中有一个变量是private方式,继承过去的方式是protected,类其中public的会变成protected,但是private的不变。

继承同名成员处理方式(父类与子类中都有相同的成员)

访问子类同名成员 直接访问即可

访问父类同名成员 需要加作用域

//继承中同名成员处理方式
class Base{
public:
  Base(){
		m_A = 100;
  }
  
  void func(){
    cout << "Base-func()调用" << endl;
  }
  
  void func(int a){
    cout << "Base-func(int a) 调用" << endl;
  }
  
  int m_A;
};

class Son : public Base{
public:
  
  Son(){
		m_A = 200;
  }
    void func()
  {
    cout << "Son-func()调用" << endl;
  }
  
  
  int m_A;
}

void test01(){
	Son s;
  cout << "Son下的m_A = "  << s.m_A << endl;
  //如果通过子类对象 访问到父类中同名成员,需要加作用域
  cout << "Base下的m_A = "  << s.Base::m_A << endl;
}

//同名成员属性处理方式
void test02(){
	Son s;
  s.func();	//直接调用 调用是子类中的同名成员
  
  //如何调用到父类中同名成员函数?
  s.Base::func();	//加入作用域
  
  //如果子类中出现和父类同名的成员函数,子类的同名成员会隐藏掉父类中所有同名成员函数
  //如果想访问到父类中被隐藏的同名成员函数函数,需要加作用域
  s.Base::func(100);
}

int main(){
	test01();
  
  test02();
}

总结:

  1. 子类对象可以直接访问到子类中同名成员

  2. 子类对象加作用域可以访问到父类同名成员

  3. 当子类与父类拥有同名的成员函数,子类会隐藏父类中同名成员函数,加作用域可以访问到父类中同名函数

继承同名静态成员处理方式

静态成员和非静态成员出席同名,处理方式一致

  • 访问子类同名成员,直接访问即可

  • 访问父类同名成员,需要加作用域

  • //继承中的同名静态成员处理方式
    
    class Base{
    public:
      static int m_A;
      
      static void func(){
    		cout << "Base -  static void func()" << endl;
      }
      
      
      static void func(int a){
        cout << "Base - static void func(int a)" << endl;
      }
    };
    
    int Base::m_A = 100;
    
    class Son : public Base{
    public:
    	static int m_A;  
      
      static void func(){
        cout << "Son - static void func()" << endl;
      }
    };
    int Son :: m_A =200;
    
    //同名静态成员属性
    void test01(){
      //1、通过对象访问
      cout << "通过对象访问:"<< endl;
      Son s;
      cout << "Son 下的 m_A= " << s.m_A << endl;
      cout << "Base下的m_A=" << s.Base::m_A << endl;
    
    	//2、通过类名访问
      cout << "通过类名访问" << endl;
      cout << "Son下m_A" << Son :: m_A << endl;
      //第一个::代表通过类名方式访问 第二个::代表访问父类作用域下
      cout << "Base下m_A" << Son :: Base :: m_A << endl;
    }
    //同名静态成员函数
    void test02(){
      //1、通过对象访问
      cout << "通过对象访问" << endl;
      Son s;
      s.func();
      s.Base::func();
      
      //2、通过类名访问
      cout << "通过类名访问" << endl;
      Son::func();
      Son::Base::func();
      
      //子类出现和父类同名静态成员函数,也会隐藏父类中所有同名成员函数
      //如果想访问父类中被隐藏同名成员,需要加作用域
      Son::Base::func(100);
    }
    
    int main(){
      test01();
      
      test02();
    }

    总结:

    同名静态成员处理方式和非静态处理方式一样,只不过有两种访问的方式(通过对象和通过类名)

继承中的对象模型

//继承中的对象模型
class Base{
public:
  int m_A;
protected:
  int m_B;
private:
  int m_C;		//父类中私有的成员属性 是被编译器给隐藏了,因此是访问不到,但是确实被继承下去了
};

class Son : public Base{
public:
  int m_D;
};

void test01(){
  //父类中所有非静态成员属性都会被子类继承下去
  cout << "size of Son=" << sizeof(Son) << endl;	//16 四个变量加起来为16
}

int main(){
  test01();
}

继承中构造和析构函数

子类继承父类后,当创建子类对象,也会调用父类的构造函数

问题:父类和子类的构造和析构顺序是谁先谁后?

//继承中的构造和析构顺序
class Base{
public:
  Base(){
    cout << "Base构造函数!" << endl;
  }
  
  ~Base(){
    cout << "Base析构函数!" << endl;
  }
}

class Son:public Base{
public:
  Son(){
    cout << "Son构造函数!" << endl;
  }
  
  ~Son(){
    cout << "Son析构函数!" << endl;
  }
};

void test01(){
	//Base b;
  //继承中的构造和析构顺序如下:
  //先构造父类,再构造子类,析构的顺序与构造的顺序相反
  Son c;		//会一并创建父类中的构造和析构函数和对象,先有父类再有子类
}

int main(){
	test01();
}

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBARVVHT1VBTElDRQ==,size_16,color_FFFFFF,t_70,g_se,x_16

总结:从上面可以看出父类的构造函数先调用、再是子类的构造函数。而析构函数则相反,先是子类的析构函数先调用、再是父类的析构函数。 

菱形继承

菱形继承概念:

  • 两个派生类继承同一个基类

  • 又有某个类同时继承者

  • 这种继承被称为菱形继承,或者钻石继承

  • watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBARVVHT1VBTElDRQ==,size_16,color_FFFFFF,t_70,g_se,x_16

    多继承语法

  • C++允许一个类中继承多个类

  • 多继承语法:

  • class 子类:继承方式 父类1 ,  继承方式 父类2...

    ⚠️:C++实际开发中不建议使用多继承开发

  • //多继承语法
    
    class Base1{
    public:
      Base1(){
        m_A = 100;
      }
      
      int m_A;
    };
    
    class Base2{
    public:
      Base2(){
        m_B = 200;
      }
      
      int m_B;
     
    };
    
    //子类 需要继承Base1和Base2
    //语法:class 子类:继承方式 父类1 , 继承方式 父类2
    class Son : public Base1 , public Base2{
    public:
      Son(){
    		m_C = 300;
        m_D = 400;
      }
    };
    
    void test01(){
      Son s;
      
      cout << "sizeof Son = "<< sizeof(s) << endl
        //当父类中出现同名成员,需要加作用域区分
      cout << "Base1::m_A = " <<s.Base1 :: m_A << endl;	
      cout << "Base2::m_A = " <<s.Base2 :: m_A << endl;
    }
    
    int main(){
      
    }

    总结:多继承中如果父类中出现了同名情况,子类使用时候要加作用域

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

C++继承(一) 的相关文章

  • 向进度条添加百分比文本 C#

    我有一个方法可以显示进程栏何时正在执行以及何时成功完成 我工作得很好 但我想添加一个百分比 如果完成 则显示 100 如果卡在某个地方 则显示更少 我在网上做了一些研究 但我无法适应我正在寻找的解决方案 这是我的代码 private voi
  • InvalidOperationException - 对象当前正在其他地方使用 - 红十字

    我有一个 C 桌面应用程序 其中我连续创建的一个线程从源 实际上是一台数码相机 获取图像并将其放在 GUI 中的面板 panel Image img 上 这必须是另一个线程 如它是控件的代码隐藏 该应用程序可以工作 但在某些机器上 我会在随
  • 每个托管线程是否都有自己对应的本机线程?

    我想知道是否在 Net 中创建托管线程 通过调用Thread Start 导致在后台创建一个本机线程 那么托管线程是否有对应的本机线程呢 如果是 当托管线程等待或睡眠时 是否意味着相应的本机线程也在等待或睡眠 是的 NET 线程映射到所有当
  • 在 C++ 中使用 matlab 结构(matlab 函数调用的返回值)(由 matlab 编译器生成的库)

    你好 我有一个相当简单的 matlab 函数 例如 function MYSTRUCT myfunc MYSTRUCT prop1 test MYSTRUCT prop2 foo MYSTRUCT prop3 42 end 我用 matla
  • 未提供参数时如何指定 C# System.Commandline 行为?

    在我的控制台应用程序中 当未提供控制台参数时 将执行我指定列表 在本例中为参数 3 的任何处理程序 调用该处理程序时 布尔参数设置为 false 但对我来说 根本不调用它更有意义 如何防止这种情况发生并显示帮助文本 using System
  • 如何将 protobuf-net 与不可变值类型一起使用?

    假设我有一个像这样的不可变值类型 Serializable DataContract public struct MyValueType ISerializable private readonly int x private readon
  • 提交后禁用按钮

    当用户提交付款表单并且发布表单的代码导致 Firefox 中出现重复发布时 我试图禁用按钮 去掉代码就不会出现这个问题 在firefox以外的任何浏览器中也不会出现这个问题 知道如何防止双重帖子吗 System Text StringBui
  • ClickOnce 应用程序错误:部署和应用程序没有匹配的安全区域

    我在 IE 中使用 FireFox 和 Chrome 的 ClickOnce 应用程序时遇到问题 它工作正常 异常的详细信息是 PLATFORM VERSION INFO Windows 6 1 7600 0 Win32NT Common
  • C中的malloc内存分配方案

    我在 C 中尝试使用 malloc 发现 malloc 在分配了一些内存后浪费了一些空间 下面是我用来测试 malloc 的一段代码 include
  • 复制目录内容

    我想将目录 tmp1 的内容复制到另一个目录 tmp2 tmp1 可能包含文件和其他目录 我想使用C C 复制tmp1的内容 包括模式 如果 tmp1 包含目录树 我想递归复制它们 最简单的解决方案是什么 我找到了一个解决方案来打开目录并读
  • 如何创建包含 IPv4 地址的文本框? [复制]

    这个问题在这里已经有答案了 如何制作一个这样的文本框 我想所有的用户都见过这个并且知道它的功能 您可以使用带有 Mask 的 MaskedTestBox000 000 000 000 欲了解更多信息 请参阅文档 http msdn micr
  • 回发后刷新时提示确认表单重新提交。我做错了什么?

    我有一个以空白 默认状态启动的仪表板 我让用户能够将保存的状态加载到仪表板中 当他们单击 应用 按钮时 我运行以下代码 function CloseAndSave var radUpload find radUpload1ID var in
  • 是否有实用的理由使用“if (0 == p)”而不是“if (!p)”?

    我倾向于使用逻辑非运算符来编写 if 语句 if p some code 我周围的一些人倾向于使用显式比较 因此代码如下所示 if FOO p some code 其中 FOO 是其中之一false FALSE 0 0 0 NULL etc
  • 如何检测表单的任何控件的变化?

    如何检测 C 中表单的任何控件的更改 由于我在一个表单上有许多控件 并且如果表单中的任何控件值发生更改 我需要禁用按钮 我正在寻找一些内置函数 事件处理程序 属性 并且不想为此创建自定义函数 不 我不知道任何时候都会触发任何事件any控制表
  • Qt - ubuntu中的串口名称

    我在 Ubuntu 上查找串行端口名称时遇到问题 如您所知 为了在 Windows 上读取串口 我们可以使用以下代码 serial gt setPortName com3 但是当我在 Ubuntu 上编译这段代码时 我无法使用这段代码 se
  • C#:帮助理解 UML 类图中的 <>

    我目前正在做一个项目 我们必须从 UML 图编写代码 我了解 UML 类图的剖析 但我无法理解什么 lt
  • 将 MQTTNet 服务器与 MQTT.js 客户端结合使用

    我已经启动了一个 MQTT 服务器 就像this https github com chkr1011 MQTTnet tree master例子 该代码托管在 ASP Net Core 2 0 应用程序中 但我尝试过控制台应用程序 但没有成
  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类
  • 无法接收 UDP Windows RT

    我正在为 Windows 8 RT 编写一个 Windows Store Metro Modern RT 应用程序 需要在端口 49030 上接收 UDP 数据包 但我似乎无法接收任何数据包 我已按照使用教程进行操作DatagramSock
  • 当我使用 OpenSSL1.1.0g 根据固定的 p 和 g 值创建 Diffie Hellman 密钥协议密钥时,应该执行哪些检查?

    您好 我尝试通过这段代码使用修复 p 和 g 参数来制作 Diffie Hellman Keysanswer https stackoverflow com a 54538811 4706711 include

随机推荐

  • 7-2 两个有序链表合并(新表不含重复元素)

    C 7 2 两个有序链表合并 新表不含重复元素 20 分 已知两个非降序链表序列S1与S2 设计函数构造出S1与S2合并后的新的非降序链表S3 要求S3中没有重复元素 输入格式 输入分两行 分别在每行给出由若干个正整数构成的非降序序列 用
  • UID卡_ID卡

    1 基本信息 M1卡 全称Mifare classic 1K 普通IC卡 0扇区不可修改 其他扇区可以反复擦写 通常我们使用的门禁卡 电梯卡都是M1卡 M1卡是NXP 恩智浦半导体 公司研发的IC卡 执行标准是ISO IEC14443 Ty
  • 微信表情的字符编号完整版【图文并茂哦!】

    图文并茂哦 Emoji表情的分类 微信表情的字符编号完整版 NLP神经网络实现在伪原创方面的运用NLP伪原创技术早期并不是很受欢迎基于主动学习的伪原创句法识别研究小发猫 人工智能的伪原创工具小发猫与普通伪原创工具的区别自媒体如何快速伪原创
  • SVN——Previous operation has not finished;run 'cleanup' if it was interupted

    前言 小编在用svn更新代码更新的时候不小心关掉了客户端 导致出现如下问题 解决方案 客户端已经给出了解决模块 按照客户端的提示去做就好了 不过还是要查一下相关的内容 以免误操作造成更多不好的结果 按照如下图所示去操作就好 打开后是这个界面
  • css背景对话框

    ts height 108rpx width 528rpx background RGBA 46 48 61 1 border radius 8rpx position absolute top 50rpx left 54rpx after
  • iOS 15适配

    写的有点晚了哈 升级iOS15之后 有没有发现你的App导航栏上的状态栏颜色变了呢 navigationBar if available iOS 15 0 UINavigationBarAppearance appearance UINav
  • [Angular]快速将Bootstrap4引入Angular9

    目录 创建一个Angular项目 Angular里面引入bootstrap 方法一 直接引用 方法二 npm安装 Angular添加表单 优化 参考链接 创建一个Angular项目 安装Node js 安装Angular CLI 使用命令行
  • unity 智能巡逻兵

    unity 智能巡逻兵 一 游戏要求 游戏设计要求 创建一个地图和若干巡逻兵 使用动画 每个巡逻兵走一个3 5个边的凸多边型 位置数据是相对地址 即每次确定下一个目标位置 用自己当前位置为原点计算 巡逻兵碰撞到障碍物 则会自动选下一个点为目
  • 关于Spring属性编辑器详解

    最近刚在研究Spring的编辑器 发现很有意思 刚好galaxystar起了一个这样贴 我想对PropertyEditor作一个详细的整理会对大家有益 特定启了这个新帖 所谓的PropertyEditor 顾名思义 就是属性编辑器 由于Be
  • Nginx配置汇总

    一 Nginx概念 Nginx是目前负载均衡技术中的主流方案 几乎绝大部分项目都会使用它 Nginx是一个轻量级的高性能HTTP反向代理服务器 同时它也是一个通用类型的代理服务器 支持绝大部分协议 如TCP UDP SMTP HTTPS等
  • hadoop.2.6.0安装hive.1.2.2

    文章目录 1 hadoop 2 6 0的安装 2 hive 1 2 2的安装 2 1 前提 2 2 解压 错误1 提示 1 hadoop 2 6 0的安装 参考 https blog csdn net qq 21383435 article
  • 请别再问我Spark的MLlib和ML库的区别

    机器学习库 MLlib 指南 MLlib是Spark的机器学习 ML 库 其目标是使实际的机器学习可扩展和容易 在高层次上 它提供了如下工具 ML算法 通用学习算法 如分类 回归 聚类和协同过滤 特征提取 特征提取 转换 降维和选择 管道
  • sharding-jdbc系列(一):概念

    前话 前段时间公司项目比较忙 天天都忙于码代码 最近好不容易项目上线了 后期就是试运行解决线上问题 要闲一些了 看了下公司以前的一些项目 发现其中居然有用到sharding jdbc 想到以前自己也使用过 但是仅仅是会用过 对一些原理还不了
  • antd pro component - EditableProTable 表单重置

    antd pro component EditableProTable 受控情况之下 改变 dataSource之后 但是表格编辑组件还是记录上次编辑状态记录的数据 没有及时更新 解决办法就是手动更新表单 其实整个表格就是一个form 开始
  • 数据分析36计(24):因果推断结合机器学习估计个体处理效应

    个体异质性为何重要 传统的因果推断分析 主要关注焦点是平均处理效应 Average Treatment Effect 许多科学和工程都会面临这样的挑战 从个性化的医疗救治方案 到定制型的营销建议都需要了解异质性处理效应 即个体层面的因果效应
  • 延时队列的几种实现方式(只有原理,并没有源码)

    延时队列 需求描述 场景一 在淘宝下了订单 过半个小时未支付就取消订单 场景二 还是淘宝 别问 问就是淘宝资深剁手党 发货后超过15天未确认就自动收货 需求分析 本质上都是超过xxx时间 就异步去做一件事 说到异步那基本上就是搞个定时任务去
  • 推荐 4 个本周 火火火火 的开源项目

    本期推荐开源项目目录 1 一个集成了主流 AI 大模型的 APP 2 模拟人类行为的小镇 3 离线 OCR 软件 4 流程图编辑框架 01 一个集成了主流 AI 大模型的 APP 该开源项目集成了主流的大语言模型 绘图模型 基于Flutte
  • 第七站:吃透JavaScript中的函数

    欢迎来到 JavaWeb的奇妙冒险 教学系列 在这里 我们将继续探索Web开发的精彩世界 本站将为你揭开JavaScript中变量的神秘面纱 让我们在学习的过程中既轻松愉快 又能掌握高质量的知识 准备好进入第七站的学习之旅了吗 让我们开始吧
  • 【C++11】右值引用和移动语义 万能引用和完美转发

    文章目录 1 右值引用和移动语义 1 1 左值引用和右值引用 1 2 右值引用的使用场景 1 3 新的类功能 2 万能引用与完美转发 2 1 万能引用的基本介绍和使用 2 2 完美转发 2 3 完美转发的实际应用场景 3 可变参数模板 3
  • C++继承(一)

    目录 继承方式 继承同名成员处理方式 父类与子类中都有相同的成员 继承同名静态成员处理方式 继承中的对象模型 继承中构造和析构函数 菱形继承 多继承语法 在多种接口需要相同输出时 C 的继承相对于传统方式更有利也更方便维护 C 继承语法 c