为了账号安全,请及时绑定邮箱和手机立即绑定

指针类型问题

父类 * p = new 子类

那么 p 里面 是父类的代码 还是子类的代码

正在回答

2 回答

先说个函数指针的概念,每个类(除了空类,就是没有方法也没有属性的类)在创建的时候,就会生成一个虚函数表指针,这个指针与普通的指针一样,存的是函数的入口地址,这是在类生成的时候就建立的。下来说几种情况:

  1. 父类实现了非virtual修饰的方法一,子类继承父类,子类没有再实现方法一,这样父类与子类的关于方法一在各自虚函数表中的地址是一样的,也就是子类可以直接用父类的方法,而不用再去实现;

  2. 父类实现了非virtual修饰的方法一,子类继承父类,子类重写了方法一,这样子类的虚函数表的方法一的地址与父类的虚函数表的方法一的地址是不同的。这时候父类指针指向子类对象的时候,调用方法一时会用父类虚函数表中方法一的入口,这样执行的就是父类方法一的实现;而子类调用方法一时,使用的是子类虚函数表中的方法一的入口,这样执行的就是子类方法一的实现。这种情况叫隐藏。

  3. 父类实现了virtual修饰的方法一,子类继承父类,子类没有再实现方法一,这样父类与子类的关于方法一在各自虚函数表中的地址是一样的,也就是子类可以直接用父类的方法,也不用再去实现;

  4. 父类实现了virtual修饰的方法一,子类继承父类,子类重写了方法一,这样子类的虚函数表的方法一的地址与父类的虚函数表中方法一的入口地址也是不同的。与第二种情况不同的是,采用virtual修饰的方法,在父类指针指向子类对象时,子类的同名方法会覆盖父类的方法的入口,也就是父类的虚函数表方法一的入口地址会被子类的虚函数表的方法一的入口覆盖,这时候父类指针执行的就是子类的方法一的实现,从而实现多态。这种情况叫覆盖。

下来说 父类 * p = new 子类; 这样的操作之后到底执行哪块代码,就得分具体情况了,但是在面向对象的编程中,多态是一个很重要的特性,所以一般建议大家对有继承关系的类加上virtual修饰。

举个例子,人都需要吃饭,而小明每次吃饭都哵嗒嘴,也就是:人 *人1 = new 小明(); 到吃饭的时候,调用人1的吃饭的方法,因为这个人是小明,所以就要有小明吃饭的特征。如果没有virtual关键字,那人人吃饭都一个样了,好无聊哦。

4 回复 有任何疑惑可以回复我~
#1

qq_圓圓_0 提问者

太感谢了,说的十分详细
2015-12-29 回复 有任何疑惑可以回复我~
#2

太阳雨下 回复 qq_圓圓_0 提问者

不客气,大家共同学习提高
2015-12-29 回复 有任何疑惑可以回复我~

实例化过程中这种写法是错误的,父类 *p=new 父类();or 子类*p=new 子类();

0 回复 有任何疑惑可以回复我~
#1

箴_理

没有错误,这体现的是is a关系
2016-07-20 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消
C++远征之多态篇
  • 参与学习       66236    人
  • 解答问题       314    个

本教程将带领大家体会面向对象三大特性中的多态特性

进入课程

指针类型问题

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信