zoukankan      html  css  js  c++  java
  • 虚函数调用中的指针类型转换以及指针所指类型的本质

      父类类型指针可指向子类对象,调用子类对象重写的虚函数,一条代码即有了不同的表现结果,也就是多态。

      很显然,子类重写的虚函数里调用的自然是子类的成员变量,父类类型指针是无法直接访问到子类的成员变量的。那么既然是父类类型指针调用的子类的虚函数,那么传给this的自然就是父类类型的指针,那么又如何能访问到子类的成员变量呢?

      细心想一下就明白了,this指针也是有类型的,其类型就是类本身类型,所以子类的虚函数中,this指针的类型就是子类类型,因此当父类类型的指针作为实参传进去时,会强制转换成子类类型指针,这样就能正确访问子类成员变量。

      如代码所示:

    Child child;
    Parent *p = &child;
    
    //如果print()是子类重写的虚函数,那么完整的print()的类型是:
    //virtual void print(Child *this);
    //p将强制转换成Child*类型,然后初始化this
    p->print();

      这里另一个实质性的问题就是,为什么父类指针已经指向了子类对象,却不能直接访问其成员变量呢?这是因为指针的解引用的结果在本质上,就是一块固定内存空间的大小。父类和子类所占内存大小一般不一样,因此解引用了父类类型指针,得到的内存空间并不是子类的内存空间。只有将父类类型指针类型强行转换成子类类型的指针,那么解引用指针后,得到的就是子类对象的内存空间了,也就可以合法访问子类内存空间中的成员变量了。

      知道了这一点,就可以用间接的方法,使指向子类对象的父类类型指针访问子类的成员变量了。如代码:

    class Parent
    {
    public:
        int a;
    
    };
    
    class Child : public Parent
    {
    public:
        int b;
    
    };
    
    int main()
    {
        Child child;
        child.b = 10;
    
        Parent *p = &child;
    
        //child对象中继承的parent成员变量统统位于栈底,这是因为构造函数先初始化父类
        //因此p+1即得到子类成员变量的首地址,即通过了父类类型指针,得到了子类对象的成员变量
        int tmp = *((int*)(p+1));
    
        //tmp将是10
        cout << "tmp=" << tmp << endl;
    
        return 0;
    }

      配以图示:

  • 相关阅读:
    [css]浮动造成的影响
    [py]django的manytomany字段和后台搜索过滤功能
    [py][lc]python高阶函数(匿名/map/reduce/sorted)
    [py][lc]python的纸牌知识点
    [js]js中类的继承
    [js]js杂项陆续补充中...
    [js]js设计模式小结
    WP10的一点小问题
    JS 判断滚动底部并加载更多效果。。。。。。。。。
    This assembly may have been downloaded from the Web. ......
  • 原文地址:https://www.cnblogs.com/demon90s/p/4663743.html
Copyright © 2011-2022 走看看