zoukankan      html  css  js  c++  java
  • 虚函数手工实现简单虚表

    /*******************************Person.h*****************************/


    #if !defined(AFX_PERSON_H__7862BC0E_A397_4133_AEEF_0F6FEF6B9F43__INCLUDED_)
    #define AFX_PERSON_H__7862BC0E_A397_4133_AEEF_0F6FEF6B9F43__INCLUDED_

    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000

    class CPerson;

    //
    定义一个成员函数指针类型
    typedef void (CPerson::*TYPE_pfn_Say)(void);
    //new
    时编译器分析不出成员函数指针多大,所以在再定义一个全局函数指针
    typedef void (*TYPE_pfn_g_Say)(void);


    class CPerson
    {
    public:
        TYPE_pfn_Say *arypfnaSayPerson;
    public:
        CPerson();
        ~CPerson();
    public:
        void SayHello(void);
        void SayGoodbye(void);
    };

    #endif // !defined(AFX_PERSON_H__7862BC0E_A397_4133_AEEF_0F6FEF6B9F43__INCLUDED_)

     

    /*******************************Person.cpp*****************************/


    #include "stdafx.h"
    #include "Person.h"
    #include <iostream.h>

    CPerson::CPerson()
    {
        //
    基类申请用来放虚表的空间,用成员函数指针数组,编译器分不清成员函数指针的大小
        //
    所以用全局函数指针数组来确定大小

        TYPE_pfn_g_Say *arypfnSayTemp = new TYPE_pfn_g_Say[4];
        arypfnaSayPerson = (TYPE_pfn_Say *)arypfnSayTemp;

        //
    初始化虚表
        arypfnaSayPerson[0] = SayHello;
        arypfnaSayPerson[1] = SayGoodbye;
    }

    CPerson::~CPerson()
    {
        if (arypfnaSayPerson)
        {
            delete [] arypfnaSayPerson;
            arypfnaSayPerson = NULL;
        }
    }


    void CPerson::SayHello(void)
    {
        cout << "CPerson say Hello" << endl;
    }

    void CPerson::SayGoodbye(void)
    {
        cout << "CPerson say goodbye" << endl;
    }

     

    /*******************************Student.h*******************************/


    #if !defined(AFX_STUDENT_H__8CA11886_59C1_4C51_B79B_BE9B243CF034__INCLUDED_)
    #define AFX_STUDENT_H__8CA11886_59C1_4C51_B79B_BE9B243CF034__INCLUDED_

    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000

    #include "Person.h"

    class CStudent;

    //
    定义一个成员函数指针类型
    typedef void (CStudent::*TYPE_pfn_SayStudent)(void);



    class CStudent : public CPerson 
    {
    public:
        TYPE_pfn_SayStudent *arypfnaSayStudent;
    public:
        CStudent();
        ~CStudent();
    public:
        void SayHello(void);   
        void SayGoodbye(void);
    };

    #endif // !defined(AFX_STUDENT_H__8CA11886_59C1_4C51_B79B_BE9B243CF034__INCLUDED_)

     

    /*******************************Student.cpp*******************************/


    #include "stdafx.h"
    #include "Student.h"
    #include <iostream.h>

    CStudent::CStudent()
    {
        //
    子类构造会高用基类构造
        //
    所以会先在基类申请虚表空间,子类直接给值就行了
        arypfnaSayStudent = (TYPE_pfn_SayStudent *)arypfnaSayPerson;
        //
    把子类的成员函数覆盖掉基类的成员函数
        arypfnaSayStudent[0] = SayHello;
        arypfnaSayStudent[1] = SayGoodbye;
    }

    CStudent::~CStudent()
    {
        arypfnaSayStudent = NULL;
    }

    void CStudent::SayHello(void)
    {
        cout << "CStudent say Hello" << endl;
    }

    void CStudent::SayGoodbye(void)
    {
        cout << "CStudent say goodbye" << endl;
    }

     

    /************************************************************************
    手工简单模拟虚函数来表现出多态性:
    写一基类Person
    sayHellosayGoodbye函数
    有一子类student
    它也有自己的sayHello, sayGoodbye函数
    请在这两个类里加入函数vsayHello, vsayGoodbye函数
    来表现出对象的多态性(分别调用自己的对应的sayHellosayGoodbye)

    成员函数指针完成

    ************************************************************************/

    #include "stdafx.h"
    #include "Student.h"

    void AllSay(CPerson *pthePerson, int nInedx)
    {
        //
    成员函数指针数组调用,pthePerson->*这一段可以理解为this指针
        (pthePerson->*pthePerson->arypfnaSayPerson[nInedx])();
    }

    int main()
    {
        CPerson thePerson;
        CStudent theStudent;

        AllSay(&thePerson, 0);
        AllSay(&thePerson, 1);
        AllSay(&theStudent, 0);
        AllSay(&theStudent, 1);

        return 0;
    }

  • 相关阅读:
    易语言软件加VMProtect壳的正确方法
    ghost系统到硬盘完后,重启进入winxp安装的画面变成了蓝屏
    万象客户端设置服务端ip保存在注册表的位置
    php乱码解决
    远程桌面Default.rdp 中各个参数的含义
    关闭自动检测磁盘
    关于collapsed margin(外边距合并)
    position定位
    grunt-replace和grunt-include-replace问题
    关于动态生成dom绑定事件失效的原因
  • 原文地址:https://www.cnblogs.com/w413133157/p/1659301.html
Copyright © 2011-2022 走看看