• 不同类型的指针


    1、思考,不同类型的指针,到底有什么区别?

      指向Animal的指针和指向Dog的指针,到底有什么区别?首先,指针的表示方法相同,指针的内容相同,都是一个int,表示地址。区别只是指向对象的类型不同(好像是废话)。这有什么意义呢? 这其实是告诉了编译器如何解释这个地址中的内存内容以及大小。也就是说,对于指向Animal 的指针,编译器把指向内容当作一个Animal,对于指向Dog 指针,编译器把指向的内容当作Dog。

    2、那么,问题来了,Animal* pa = new Dog(),是怎么做到运行期多态的呢?

      pa的表面类型是Animal,真实类型是Dog,编译器在编译时只知道pa的表面类型,那么把pa当作Animal来解释,能不能做到运行时多态呢?简单回忆一下,Animal对应一个虚方法表(虚方法表可认为一个数组,元素是方法指针),Dog对应一个虚方法表,可以认为Dog中的虚方法表是整体拷贝了Animal 的虚方法表,对于重写的方法在对应的位置换上重写后的方法,对于新增的虚方法,加在虚方法表的最后。对象的内存中只有实例字段和vptr,vptr指向vtbl(虚方法表),根据对应的方法,在vtbl对应的位置上,找到方法指针,进而找到方法。

      对于Animal对象和Dog对象,可认为在相同位置都放着vptr。这样的话,pa指向内存中的一个Dog对象,我把指向的内容当作Animal来解释,也能找到vptr,但是这个vptr指向Dog类的虚方法表。由于Dog类中虚方法表,是在Animal虚方法表的基础上,进行了替换,这就构成了运行时多态。

    3、现在考虑,Animal和Dog都有一个Name字段,pa->Name 访问是Animal的字段,还是Dog 的字段呢?  

      Animal对象和Dog对象的内存分布,举例来说,Animal对象为:age,Name,vptr,那么Dog对象的内存分布就是age,Name,vptr,Name。前面Name的作用域是父类,后面Name的作用域是子类,子类作用域小于父类作用域。

      编译器把pa指向的内容,当作Animal来解释,取的是Animal的字段。如果想要取出Dog 的Name字段怎么办呢?当然是,告诉编译器,把pa指向的内容当作Dog来解释,强制类型转化为Dog指针。

  • 相关阅读:
    root用户没有权限编辑其他用户处理
    php中 被遗忘的函数
    erlang file操作(IO编程)
    Linux下的MySQL自动备份脚本
    这就是传说中让理科生沉默,让文科生落泪的文理综合体(转)
    LINUX 忘记root密码
    php中 被遗忘的函数
    分页显示的常用操作方法
    php 接口类:interface
    php垃圾回收机制分析
  • 原文地址:https://www.cnblogs.com/nzbbody/p/3480876.html
Copyright © 2020-2023  润新知