首页 > 其他分享 >向上/下造型

向上/下造型

时间:2023-11-13 16:12:15浏览次数:29  
标签:向上 int 造型 子类 Print 父类 指针

  • 孔子云:杀鸡用牛刀者,所谓向上造型也。

向上造型

显然孔子没说过开头那段话。

假设我们有一个父类 A 类,一个子类 B 类。

class A
{
public:
  A() : i(10) {}
  void Print()
  {
    cout << "a.i = " << i << endl;
  }
private:
  int i;
};

class B : public A
{
public:
  B() : j(10) {}
  void Print()
  {
    cout << "b.j = " << j << endl;
  }
private: 
  int j;
};

在类的组合与继承一节中,我们了解到,B 类继承了 A 类所有的东西。

那么实际上,我们可以把 B 类看成是一种特殊的 A 类。

打个比方:

  • 子类是学生,父类是人。你可以认为我不是学生,而从人的角度来审视我。人会做的事情学生都会做。
  • 同样的,子类是 B,父类是 A,你可以把 B 看成一种特殊的 A,A 会做的事情 B 也都会做,A 不会做的事情 B 也会做,所以我们把 B 当作 A 类使用是完全合理的 (这就解释了孔子为什么说杀鸡用牛刀)

所谓向上造型,就是把子类当作父类来使用的意思。

因此我们把父类的指针指向子类的对象是合法并且安全的。

int main()
{
  A a;
  B b;
  A* p = &b;
}

p 指针可以调用 b 中所有从父类继承来的 public 变量和方法。

向上造型会屏蔽子类函数

我们现在来做一个实验,注意到父类和子类中均有 Print 的方法,现在我们执行 p -> Print();

程序输出了 a.i = 10 ,而不是 b.j = 10

按照类的继承中的函数名隐藏原则,子类会屏蔽掉父类的同名(及其所有重载)函数。

p 指针是把 b 视为一个 A 类,而 A 类中只有一个 Print 函数,这时反而是子类的函数被直屏蔽掉了,因此 p 指针调用的是父类 A 中的 Print 方法。

同样的理由,p 指针也无法调用子类 public 中的方法和变量,因为它们全部被屏蔽掉了。

int main()
{
  A a;
  B b;
  A* p = &b;
  //p -> B::Print();
  //提示报错 “B::Print不是 A 或 A 的父类中的成员”
}

当我们选择向上造型的时候,父类的父类以及之前的所有父类中 public 的方法都可以被调用,父类的子类及之后的所有子类中 public 的方法全部无法调用。

向下造型

  • 人是父类,学生是子类,人不会写作业,学生会写作业。你在人群里抓了一个人出来,让他写作业。

这显然有两种可能,第一种:你抓住的这个人正好是学生,那么他可以执行你“写作业”的命令。

第二种:他不是个学生,无法执行“写作业”的命令,这就比较危险了。

向下造型是不安全的,因为你不知道一个对象到底会不会做某件它的子类会做的事。

因此,我们不建议在程序中使用向下造型的方法。

但是向下造型可以让我们实现一些 邪恶的 操作,比如这样:

int main()
{
  B b;

  int* p = (int*) &b;
  *p = 15;
  p ++;
  *p = 20;
  b.A::Print();
  b.Print();

  return 0;
}

我们强制把对象 b 向下造型为 int 类型,然后通过 int* 类型的指针调用它。

然后我们尝试输出 b 类中的私有变量 i 和 j,看看会发生什么。

output:
a.i = 15
b.j = 20

发现 private 中的数据被成功从外部修改了,这说明两个问题:

  1. 我们通过向下造型取消了私有变量的访问限制。
  2. 我们通过指针自加的操作从父类中的 i 移动到了子类中的 j ,这说明在继承父类的时候,子类的变量和从父类继承来的变量之间地址是连续的。

标签:向上,int,造型,子类,Print,父类,指针
From: https://www.cnblogs.com/zaza-zt/p/17829383.html

相关文章

  • C++的向上转型
    在C/C++中经常会发生数据类型的转换,例如将int类型的数据赋值给float类型的变量时,编译器会先把int类型的数据转换为float类型再赋值;反过来,float类型的数据在经过类型转换后也可以赋值给int类型的变量。数据类型转换的前提是,编译器知道如何对数据进行取舍。例如:inta=......
  • 区块-自动自下向上移动(字幕滚动)
    示例图引入组件importautoScrollfrom'./components/autoMove.vue' 页面使用组件<divclass="pro-body"><autoScroll:list="list":speed="0.5":waitTime="2000"......
  • 【UEC++游戏案例】向上的小松饼
    一.效果与资源准备1.1游戏演示效果效果:00-课程演示_哔哩哔哩_bilibili  1.2游戏资产素材与源码素材与源码:提示信息-SiKi学院|SiKi学堂-unity|u3d|虚幻|ue4/5|java|python|人工智能|视频教程|在线课程  1.3前期准备创建无初学者内容的空项目将素材文......
  • 自底向上的语法分析,闭包、GOTO函数
    自底向上的语法分析一、一个串ω归约(reduction)为文法开始符号的过程关键问题:1.何时进行规约,2.用哪个产生式规约句柄右边的串ω一定只包含终结符号。如果文法是无二义性的,那么文法的每个右句型都有且只有一个句柄二、LR(0)自动机Automaton项1.定义:产生式加上位于体中......
  • 向上管理的两个职场案例
    之前分享过很多职场成长的内容,其中也聊了很多关于向上管理工作汇报的个人经验,最近好几个同学在公众号后台留言咨询,有没有比较实际的向上管理案例可以分享,想参照学习一下。正好,这几天在技术交流群和知识星球内部,遇到了几个典型的案例。这篇文章我会以遇到的这两个案例为例,为大家......
  • 三分钟带你搞懂什么是向上转型和向下转型
    什么是向上转型?通过在网上查了资料,和普遍的介绍,一句话总结就是“父类引用指向子类对象”,例:Humanh=newHuman();h.eat();//人类Animala=newAnimal();a.eat();//动物//父类-Human,子类-Animal,a-父类引用,newHuman()-子类对象Animala=newHuman();//向上转型 向上转......
  • OpenCascade 开源的三维建模几何造型开发平台
    官方文档 https://dev.opencascade.org/doc/overview/html/index.htmlOpenCASCADE(简称OCC)平台是由法国MatraDatavision公司开发的CAD/CAE/CAM软件平台,可以说是世界上最重要的几何造型基础软件平台之一。OpenCASCADE是一套开放原始码的CAD/CAM/CAE几何模型核心,源自于法国......
  • 【gdb】向上或向下切换函数堆栈帧
    向上或向下切换函数堆栈帧1.例子:#include<stdio.h>intfunc1(inta){return2*a;}intfunc2(inta){intc=0;c=2*func1(a);returnc;}intfunc3(inta){intc=0;c=2*func2(a);retur......
  • 面向对象_向下转型_向上转型
    1packagecom.msb9;23publicclassAnimal{4intage;5publicvoidshout(){6System.out.println("小动物在大声叫");7}8}1packagecom.msb9;23publicclassPigextendsAnimal{4doubleweight;5publicvoidsh......
  • 按下按钮后页面的滚动条向下(或向上)滑动,松开之后便停留在当前位置的效果如何实现?
    网友问题?客户要求做一个框架,按下小框架页面中的“上翻”或者“下翻”按钮后,大框架页面便随之向上(或向下)滚动,松开按钮滚动停止,并停留在当前位置,如何解决?解决方案如下:-----------------mm.htm:-----------------<framesetrows="*,20%"><framename="main"src='liu.htm'target="fo......