• c++中虚函数的一点说明


    先帖段代码

    class A{
    public:
        virtual void f1(){puts("A");}
        virtual void f2(){f1();}
    };
    
    class B:public A{
    public :
        void f1(){puts("B");}
        void f2(){f1();}
    };
    
    class C:public A{
    public:
        void f1(){puts("C");}
    };
    int _tmain(int argc, _TCHAR* argv[])
    {
        A a; B b; C c;
        a.f2();
        b.f2();
        c.f2();
        printf("
    ");
    
        a.f1(); a.f2();
        a=b;//没有效果?
        a.f1();    a.f2();
        printf("
    ");
    
        class A *pa=NULL;
        pa=&b;
        pa->f1();
        pa->f2();
        pa=&c;
        pa->f1();
        pa->f2();
        printf("
    ");
        
        return 0;
    }

    简单说明下,基类A有两个虚函数,B继承了A同时重载了这两个虚函数,C继承了A但只重载了一个虚函数

    a.f2(), b.f2(), c.f2()这三句结果分别为A B C,因为A的虚表中的函数是A::f1() 和A::f2(),而B的虚表中的函数是B::f1() 和B::f2(),C中的虚表中内容是C::f1() 和A::f2(),这个没什么问题。

    本段代码难点在接下来的a=b这句,本以为在执行这句赋值语句后a的虚表的内容会发生变化,就是说a.vftable(这是一个指针)会变成b.vftable,但结果a的虚表仍指向原来的内容,指针并未发生改变,这是为什么呢?

    在A类中重载A& operator=(A& b) { puts("operator=()");  return b; },发现虽然执行此函数,但a的内容没有因此改变,难道是虚表是不会被赋值运算符改变?

    为了验证虚表和普通成员变量不同,我们在A中添加了一个成员变量a,让B中的这个继承而来的变量a和A中的a不同,测试在赋值时A中的a是否因此发生改变,具体修改代码如下

    class A{
    public:
        virtual void f1(){puts("A");}
        virtual void f2(){f1();}
        A(int n=0):a(n){}
    protected:
        int a;
        
    };
    
    class B:public A{
    public :
        void f1(){puts("B");}
        void f2(){f1();}
        B(int n=5):b(n){//a是A的成员变量,虽然被B继承,但仍不能在初始化列表初始化
            a=n+1;
        }
    protected:
        int b;
    };


    这样B中的a默认会为6,而A中的a默认为0,执行a=b发现,a中的a已经变成了6,说明这句赋值后a中的成员变量被修改,但虚表指针没有被修改!!!

    至于为什么赋值不影响虚表,这个应该是可以理解的,属于设计时有意为之,虚表和虚函数的存在是为了多态,如果允许其被修改,则会导致失去多态性

  • 相关阅读:
    Linux OS共享文件
    源代码安装软件-MySQL
    细说Linux权限
    Linux进程作业的查看和杀死
    Linux_破解密码-营救模式
    找不同diff-打补丁patch
    WINDOWS自带md5校验工具
    猪,兔,等动物解剖平面图
    利用mimikatz破解远程终端凭据,获取服务器密码
    PHP中通过bypass disable functions执行系统命令的几种方式
  • 原文地址:https://www.cnblogs.com/abc123456789/p/3433456.html
Copyright © 2020-2023  润新知