zoukankan      html  css  js  c++  java
  • c++ 继承类强制转换时的虚函数表工作原理

    本文通过简单例子说明子类之间发生强制转换时虚函数如何调用,旨在对c++继承中的虚函数表的作用机制有更深入的理解。

    #include<iostream>
    using namespace std;
    
    class Base
    {
    public:
        virtual void f()
        {
            cout<<"Base::f()"<<endl;
        }
    };
    
    class child1:public Base
    {
    public:
        virtual void f()
        {
            cout<<"child1::f()"<<endl;
        }
    
        virtual void a()
        {
            cout<<"child1::a()"<<endl;
        }
    };
    
    class child2:public Base
    {
    public:
        virtual void f()
        {
            cout<<"child2::f()"<<endl;
        }
    
        virtual void b()
        {
            cout<<"child2::b()"<<endl;
        }
    
        virtual void a()
        {
            cout<<"child2::a()"<<endl;
        }
    };
    
    int main()
    {
    
    
        child1 c1;
        child2* pc21=(child2*)&c1;
        pc21->b();//输出 child1::a()
    // pc21->a();//访问越界,程序运行时崩溃
    child2 c2; child1* pc12=(child1*)&c2; pc12->a();//输出 child2::b() return 0; }

    结论:

      1、通常的类型强转是告诉编译器必须按照指定结构的内存布局来解析对应内存,如上例中“child2* pc21=(child2*)&c1; ”,编译器会把c1对应的内存来当做类child2的内存布局来解析。因为在类child2的虚函数表中,共存在三个函数,分别为f() b() a(),其中函数b()是第二个,因此编译器就会把对象c1对应的内存来当做类child2的内存布局来解析(注意内存里的内容不变,还是c1的,即为类child1的内存布局,在这里只有虚函数表),此时在类child1的虚函数表中也找第二个函数,找到了函数a(),因此输出“child1::a()”,运行正常。这种行为可能是危险的,若使用的内存布局并不适合真实内存,很可能造成访问越界等问题(如上例中的“pc21->a();”,这次就在类B的虚函数表中找第三个函数,结果没有找到(访问越界),函数运行时崩溃。),因此使用强制转换操作时应特别注意。

      2、通过上述例子可知,虚函数在虚函数表中的存储顺序是与声明顺序一致的,而不是虚函数名字的字符串排序,如本例中为f() b() a(),虽然编程时的自动补全提示框中显示的顺序是a() b() f(),但可能已经经过内部优化,这个就不太清楚了(也不是我们要研究的内容)。

     

    『注:本文来自博客园“小溪的博客”,若非声明均为原创内容,请勿用于商业用途,转载请注明出处http://www.cnblogs.com/xiaoxi666/』
  • 相关阅读:
    20165226 2017-2018-4 《Java程序设计》第8周学习总结
    20165226第二次实验
    结对编程练习-四则运算(第一周)
    20165226 2017-2018-4 《Java程序设计》第7周学习总结
    20165226 2017-2018-4 《Java程序设计》第6周学习总结
    实验一 Java开发环境的熟悉
    20165226 2017-2018-3 《Java程序设计》第5学习总结
    第四周课下作业
    第4周学习总结
    第三周学习
  • 原文地址:https://www.cnblogs.com/xiaoxi666/p/6391638.html
Copyright © 2011-2022 走看看