zoukankan      html  css  js  c++  java
  • 还是虚函数那些事

    关于C++虚函数的一些具体介绍,参见博客虚函数表解析(转至陈皓),就其中涉及的一些问题与大家分享一下。

    先来看一段代码:

    #include <iostream>
    using namespace std;
    
    typedef void (*Fun)(void);
    class BaseA
    {
    public:
    	virtual void A1(){cout<<"A1"<<endl;}
    	virtual void A2(){cout<<"A2"<<endl;}
    	virtual void A3(){cout<<"A3"<<endl;}
    };
    class BaseB
    {
    public:	
    	virtual void B1(){cout<<"B1"<<endl;}
    	virtual void B2(){cout<<"B2"<<endl;}
    	virtual void B3(){cout<<"B3"<<endl;}
    };
    class BaseC:public BaseA,public BaseB
    {
    public:
    	virtual void A1(){cout<<"C.A1"<<endl;}
    	virtual void A2(){cout<<"C.A2"<<endl;}
    	virtual void A3(){cout<<"C.A3"<<endl;} 
    	virtual void B1(){cout<<"C.B1"<<endl;}
    	virtual void B2(){cout<<"C.B2"<<endl;}
    	virtual void B3(){cout<<"C.B3"<<endl;}
    private:
    	virtual void C1(){cout<<"C1"<<endl;}
    	virtual void C2(){cout<<"C2"<<endl;}
    	virtual void C3(){cout<<"C3"<<endl;}
    };
    
    int main()
    {
       Fun fun=NULL;
      BaseA* baseA1 = new BaseC;
      BaseB* baseB1 = new BaseC;
      BaseA* baseA2 = (BaseA*)(void*)baseB1;
      BaseB* baseB2 = (BaseB*)(void*)baseA1;
    
    
      cout<<"baseA1->A1()=";baseA1->A1();
      cout<<"baseB1->B1()=";baseB1->B1();
      cout<<"baseA2->A1()=";baseA2->A1();
      cout<<"baseB2->B1()=";baseB2->B1();
      fun= (Fun)*((int*)*(int*)(baseA1)+3); 
      fun();
      //system("pause");
    	return 0;
    }
    

    这里有必要首先解释一下 typedef  void (Fun*)(void);这部分摘自百度知道http://zhidao.baidu.com/link?url=FfhL3LI823olsaln6p-KBKU-BercosGNFxgIpaMNS_ErverXjrenlu1n3NfBd75qfwdw170Aljmk-8YkdaraPa

    定义一个函数指针类型。
    比如你有三个函数:
    void hello(void) { printf("你好!"); }
    void bye(void) { printf("再见!"); }
    void ok(void) { printf("好的!"); }

    typdef void (*funcptr)(void);
    这样就构造了一个通用的函数
    你用的时候可以这样:
    void speak(int id)
    {
       funcptr words[3] = {&hello, &bye, &ok};
       funcptr fun = words[id];
       (*fun)();
    }

    这样的话,如果speak(0)就会显示“你好!”
    speak(1)就会显示“再见!”
    speak(2)就会显示“好的!”

    用于处理参数和返回值的形式都一样,但是功能不确定的一组函数,可以使用函数指针。

    比如算术运算符,加、减、乘、除,都可以用typedef int (*calc)(int,int)代表,等等
    /***************************************************************************************************************************************************************/

    结果会显示什么呢?

    baseA1->A1()=C.A1
    baseB1->B1()=C.B1
    baseA2->A1()=C.B1
    baseB2->B1()=C.A1
    C1

    为什么baseA2->A1() =C.B1? 为什么baseB2->B1()=C.A1?  相信了解C++虚函数机制 都明白是怎么回事

    重点我们放在 fun() 上,显示结果为C1! 不知有木有看到,在类BaseC中的C1是声明在private域中的,但是我们却可以通过操作BaseA1来访问私有函数,(至于为什么可以访问,再次建议先阅读转载文章,理清C++虚函数的机制) ,这一点足见C++在安全性上的考虑是欠缺的,至少可以说是不严谨的。

  • 相关阅读:
    「程序员思维训练」1. 读前声明
    获取apk的MD5或SHA1签名信息
    随用随记:超图小tips(长期更新ing)
    ajax上传大附件报错:413 Request Entity Too Large
    利用input file 上传文件调用ajax保存到服务器(含后台代码)
    软工课程总结
    开发体验心得总结
    结对项目 稳定版四则运算系统
    Week3 关于“微软必应词典客户端”的案例分析
    Week2 代码复查
  • 原文地址:https://www.cnblogs.com/ainima/p/6331263.html
Copyright © 2011-2022 走看看