c++基本使用--名字遮蔽与类作用域/继承的特殊关系

2023-11-13

名字遮蔽:基类的成员函数和派生类的成员函数不会构成重载,如果派生类有同名函数,那么就会遮蔽基类中的所有同名函数。

名字遮蔽:如果派生类中的成员(包括成员变量和成员函数)和基类中的成员重名,通过派生类对象或者在派生类的成员函数中使用该成员时,将使用派生类新增的成员,而不是基类的。

当存在继承关系时,基类的作用域嵌套在派生类的作用域中。如果成员在派生类的作用域中已经找到,就不会在基类作用域中继续查找;如果没有找到,则继续在基类作用域中查找。

在这里插入图片描述

基类的成员函数和派生类的成员函数不会构成重载,如果派生类有同名函数,那么就会遮蔽基类中的所有同名函数。

基类
在这里插入图片描述
派生类
在这里插入图片描述
在这里插入图片描述
派生类将基类覆盖掉了,就是派生类和基类不能重载。
在这里插入图片描述

将派生类的注释掉,基类函数实现重载
在这里插入图片描述
在这里插入图片描述

类作用域

  1. 在成员名前面加类名和域解析符可以访问对象的成员。
  2. 如果不存在继承关系,类名和域解析符可以省略不写。
  3. 当存在继承关系时,基类的作用域嵌套在派生类的作用域中。如果成员在派生类的作用域中已经找到,就不会在基类作用域中继续查找;如果没有找到,则继续在基类作用域中查找。
  4. 如果在成员的前面加上类名和域解析符,就可以直接使用该作用域的成员。

在类的作用域之外,普通的成员只能通过对象(可以是对象本身,也可以是对象指针或对象引用)来访问,静态成员可以通过对象访问,也可以通过类访问。

#include <iostream>         // 包含头文件。
using namespace std;        // 指定缺省的命名空间。
               
class A {        // 基类
public:
    int m_a=10;
    void func() { cout << "调用了A的func()函数。\n"; }
};
               
class B :public A {       // 子类
public:
    int m_a = 20;
    void func() { cout << "调用了B的func()函数。\n"; }
};
           
class C :public B {       // 孙类
public:
    int m_a = 30;
    void func() { cout << "调用了C的func()函数。\n"; }
    void show() {
        cout << "C::m_a的值是:" << C::m_a << endl;
        cout << "B::m_a的值是:" << B::m_a << endl;
        cout << "A::m_a的值是:" << B::A::m_a << endl;
    }
};
           
int main()
{           
    C c;
    cout << "C::m_a的值是:" << c.C::m_a << endl;
    cout << "B::m_a的值是:" << c.B::m_a << endl;
    cout << "A::m_a的值是:" << c.B::A::m_a << endl;
    c.C::func();
    c.B::func();
    c.B::A::func();
}

在一个例子:
基类:
在这里插入图片描述
在这里插入图片描述

派生类:
在这里插入图片描述
在这里插入图片描述

继承的特殊关系

派生类和基类之间有一些特殊关系。

  1. 可以把派生类对象赋值给基类对象(包括私有成员),但是,会舍弃非基类的成员。
#include <iostream>         // 包含头文件。
using namespace std;        // 指定缺省的命名空间。

class A {        // 基类
public:
    int m_a=0;
private:
    int m_b=0;
public:
    // 显示基类A全部的成员。
    void show() { cout << "A::show() m_a=" << m_a << ",m_b=" << m_b << endl; }
    // 设置成员m_b的值。
    void setb(int b) { m_b = b;  }
};

class B :public A        // 派生类
{
public:
    int m_c=0;
    // 显示派生类B全部的成员。
    void show() { cout << "B::show() m_a=" << m_a << "m_c=" << m_c << endl; }
};

int main()
{

    A a;
    B b;

    b.m_a = 10;
    b.setb(20);
    b.m_c = 30;

    a.show();
    a = b;
    b.show();

    // B b;
    // A* a = &b;

    // b.m_a = 10; 
    // b.setb(20);          // 设置成员m_b的值。
    // b.m_c = 30;
    // b.show();            // 调用的是B类的show()函数。

    // a->m_a = 11;
    // a->setb(22);          // 设置成员m_b的值。
    // // a->m_c = 30;
    
    // a->show();         // 调用的是A类的show()函数。
}
  1. 基类指针可以在不进行显式转换的情况下指向派生类对象。
  2. 基类引用可以在不进行显式转换的情况下引用派生类对象。
  3. 如果函数的形参是基类,实参可以用派生类。

基类指针或引用只能调用基类的方法,不能调用派生类的方法。

#include <iostream>         // 包含头文件。
using namespace std;        // 指定缺省的命名空间。

class A {        // 基类
public:
    int m_a=0;
private:
    int m_b=0;
public:
    // 显示基类A全部的成员。
    void show() { cout << "A::show() m_a=" << m_a << ",m_b=" << m_b << endl; }
    // 设置成员m_b的值。
    void setb(int b) { m_b = b;  }
};

class B :public A        // 派生类
{
public:
    int m_c=0;
    // 显示派生类B全部的成员。
    void show() { cout << "B::show() m_a=" << m_a << "m_c=" << m_c << endl; }
};

int main()
{

    B b;
    A* a = &b;

    b.m_a = 10;
    b.setb(20);
    b.m_c = 30;
    b.show();

    a->m_a=10;
    a->setb(20);
    a->show();

    // B b;
    // A* a = &b;

    // b.m_a = 10; 
    // b.setb(20);          // 设置成员m_b的值。
    // b.m_c = 30;
    // b.show();            // 调用的是B类的show()函数。

    // a->m_a = 11;
    // a->setb(22);          // 设置成员m_b的值。
    // // a->m_c = 30;
    
    // a->show();         // 调用的是A类的show()函数。
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++基本使用--名字遮蔽与类作用域/继承的特殊关系 的相关文章

随机推荐

  • Go开发工具

    http studygolang com articles 1678 1 4 Go开发工具 本节我将介绍几个开发工具 它们都具有自动化提示 自动化fmt功能 因为它们都是跨平台的 所以安装步骤之类的都是通用的 LiteIDE LiteIDE
  • 【ML on Kubernetes】第 3 章:探索 Kubernetes

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • SCPI 语言简介

    电子负载中需要用到 所以记录下 来源是德科技 SCPI 可编程仪器的标准命令 是一种基于 ASCII 的仪器编程语言 供测试和测量仪器使用 SCPI 命令采用分层结构 也称为树系统 相关命令归组于共用结点或根 这样就形成了子系统 下面一部分
  • FIO的基本概念

    对于FIO 其是一个10测试工具 可以运行在多种操作系统上 用来测试本地磁盘 网络存储等的性能 FIO有以下基本概念 大家可以先了解一下 1 基本概念 I O类型 顺序读 顺序写 随机读 随机写 块大小 读写时规定的block size 一
  • Keras入门(二)模型的保存、读取及加载

    本文将会介绍如何利用Keras来实现模型的保存 读取以及加载 本文使用的模型为解决IRIS数据集的多分类问题而设计的深度神经网络 DNN 模型 模型的结构示意图如下 具体的模型参数可以参考文章 Keras入门 一 搭建深度神经网络 DNN
  • Mathematica定义函数

    Mathematica定义函数时有点特殊 需在变量后加一个下划线 具体见下面示例 上面示例中定义函数时用的是 其实也可以用 这两个有什么区别呢 具体见下面示例便知 总结 Mathematica定义函数时 变量后面应加一个下划线 然后尽量用
  • DCDC电源负载瞬态响应分析

    DCDC电源负载瞬态响应分析 负载瞬态响应 输出电压过冲现象及其产生原因 如何改善输出电压过冲 负载瞬态响应 当负载电流突然增大或减小时 在us或ns时间内发生较大变化 变化量设置为80 满载输出电流 输出电压的瞬态响应 输出电压过冲现象及
  • springboot处理 json 转换成 实体对象

    可以使用 RequestBody PostMapping add public Result add RequestBody LogisticsDemand demand if demand getRefreshTime null dema
  • Latex-遇到的各种公式和特殊字符

    用的是OverLeaf Sigmoid的写法 begin equation sigma x frac 1 1 e x end equation Softmax的写法 begin equation sigma t i frac e t i s
  • 在Linux(Ubuntu) 中安装mysql服务器并开启远程访问

    在以linux为内核的有centos和ubuntu 推荐大家使用ubuntu 因为使用的人数多 出现了问题方便及时解决问题 一 创建一个云主机 ssh root 39 107 227 105 The authenticity of host
  • 华为OD机试(JAVA)真题II

    华为题库已换 后续会令启专栏更新最新版 介意的勿订阅 介意的勿订阅 介意的勿订阅 华为机试有三道题目 第一道和第二道属于简单或中等题 分值为100分 第三道为中等或困难题 分值为200分 总分为400分 150分钟考试时间 之前通过为150
  • vs2019MSDN(离线帮助文档)的下载与使用

    像这样搬砖的事情最烦了 在这里给大家总结一下步骤 本文参考 https blog csdn net weixin 41234001 article details 103308659 MSDN是vs的一个离线帮助文档 相当于帮助手册 1 检
  • Java中Map.Entry详解

    关于HashMap的详细介绍请参考Java基础 HashMap集合 1 Map Entry简介 Map是java中的接口 Map Entry是Map的一个内部接口 Map提供了一些常用方法 如keySet entrySet 等方法 keyS
  • React16.3新的生命周期详解

    一 React v16 0前的生命周期 1 1 第一个是组件初始化 initialization 阶段 也就是以下代码中类的构造方法 constructor Test类继承了react Component这个基类 也就继承这个react的基
  • skipped by case

    void func void int x switch x case 0 int i 1 error skipped by case 1 int j 1 ok initialized in e
  • 【转载】 C#中使用Count方法获取List集合中符合条件的个数

    很多时候操作List集合的过程中 我们需要根据特定的查询条件 获取List集合中有多少个实体对象符合查询条件 例如一批产品的对象List集合 如果这批产品的不合格数量大于10则重点备注 在C 中可以自己写for循环语句来逐条判断条件来实现
  • buuctf web [极客大挑战 2019]LoveSQL

    又是这样的界面 这糟糕的熟悉感 依旧使用上题套路 用户名 admin or 1 1 密码 1 有一串很像flag的字符 但是很可惜 这不是flag 看了一眼源代码 没有可以跳转的页面 要换个思路了 重新查看题目 发现输入的东西在check
  • Error message & blank display while ZH-cn locale in ai2

    需要修改源码2个文件 1 appinventor sources appinventor appengine war login jsp
  • Allegro修改原点位置

    1 打开Setup菜单栏的Change Drawing Origin命令 在PCB设计界面中 鼠标单击要设置原点的位置即可 2
  • c++基本使用--名字遮蔽与类作用域/继承的特殊关系

    名字遮蔽与类作用域 继承的特殊关系 名字遮蔽 基类的成员函数和派生类的成员函数不会构成重载 如果派生类有同名函数 那么就会遮蔽基类中的所有同名函数 类作用域 继承的特殊关系 名字遮蔽 基类的成员函数和派生类的成员函数不会构成重载 如果派生类