• C++:虚函数


    1.基本概念

      C++中的虚函数主要是为了实现多态,就是可以通过父类的指针指向子类的实例并调用子类的成员函数。虚函数有虚函数和纯虚函数,其中纯虚函数是必须在子类中实现的,否则无法实例化该子类。

      纯虚函数的格式:

    virtual void fun()=0;

      虚函数的实现是通过虚函数表(vfptr),每个父类都有一个虚函数表,父类在每个子类的实例中都会自动生成一个虚函数表,可以通过以下方式得到该虚函数表:

    typedef void(*fun)(void);
    
    Base b;
    fun pfun = NULL;
    cout<<"虚函数表地址:"<<(int*)(&b)<<endl;
    cout<<"第一个虚函数地址:"<<(int*)*(int*)(&b)<<endl;
    //调用第一个虚函数
    pfun=(fun)(*)((int*)*(int*)(&b));
    pfun();

      虚函数表的结构:

      在表中,Base是父类,Derive是子类,当子类中重新实现了父类的虚函数,则相应的虚函数在表中就被覆盖了,而没有重新实现的保留着父类的实现(纯虚函数必须被子类重新实现)

      在多重继承中,每个父类都会在子类实例中生成一个虚函数表:

    2.实例

    #include <iostream>
    using namespace std;
    
    class A{
    
    public:
        virtual void  fun1(){ cout << "Afun1()" << endl; }
        virtual void  fun2(){ cout << "Afun2()" << endl; }
        virtual void  fun3() = 0;
        void fun4(){ cout << "Afun4()" << endl; }
    
    
    };
    class B :public A{
    
    public:
        virtual void fun1(){ cout << "Bfun1()" << endl; }
        void fun3(){ cout << "Bfun3()" << endl; }
        void fun4(){ cout << "Bfun4()" << endl; }    
    
    };
    class C :public A{
    
    public:
        virtual void fun1(){ cout << "Cfun1()" << endl; }
        virtual void fun2(){ cout << "Cfun2()" << endl; }
        void fun3(){ cout << "Cfun3()" << endl; }
        void fun4(){ cout << "Cfun4()" << endl; }
    
    };
    
    typedef void(*fun)(void); //函数指针
    
    int main()
    {
        fun pfun = NULL;
        A *pa;
        B b;
        C c;
    
        cout << "虚函数表地址:" << (int*)(&b) << endl;
        cout << "第一个虚函数的地址:" << (int*)*(int*)(&b) << endl;
        pfun = (fun)*((int*)*(int*)(&b));
        pfun();//调用第一个虚函数
    
        pa = &b;
        pa->fun1();
        pa->fun2();
        pa->fun3();
        pa->fun4();
        
        pa = &c;
        pa->fun1();
        pa->fun2();
        pa->fun3();
        pa->fun4();
        return 0;
    }

      该实例的虚函数表如下:

    ------------ 转载请注明出处 ------------
  • 相关阅读:
    WPF自定义RoutedEvent事件代码段
    微信聊天和通讯录按钮样式
    【转】c#、wpf 字符串,color,brush之间的转换
    模块式开发
    通过属性进行浅拷贝
    【转】string.Format对C#字符串格式化
    酷学习笔记——前言
    C# 连蒙带骗不知所以然的搞定USB下位机读写
    C# Ioc、DI、Unity、TDD的一点想法和实践
    虹软人脸识别速度测试征集
  • 原文地址:https://www.cnblogs.com/whlook/p/6482619.html
Copyright © 2020-2023  润新知