zoukankan      html  css  js  c++  java
  • C++多态性的浅析

      多态性是C++的一个重要特性,【不扯淡直接进入正题】

      灵活运用多态,首先得知道类之间的继承。  当B继承了A类后,一般都是公有继承。  B的实例化对象的内存空间结构若是了解 就可以合理利用多态了。

      A的内存空间我们假定为a,  

      B的内存空间是这样的结构:   a

                     b新增的地址空间

      a+b 就是B实例化对象的地址空间了。

     

         在类的空间里面 都会有虚函数的信息表,【没有虚函数 就没法考虑多态】;A有A的虚函数信息表,B有B的虚函数信息表。

        结合下面例子来理解: class A{public: void fun1(){ printf(”A1 ");}    virtual  void fun2(){printf ("A2 ");}     };

     

               class B :public A{   public:void fun1(){ printf(”B1 ");}     void fun2(){printf("B2 ");}   };

        int main()

     {  

         A a; B b;

         A* p = &a;

        p->fun2();

        p = &b;

        p-> fun2();

        p->fun1();

       }

     

      fun2 为虚函数, 第一个输出全在A 里面。跟B 没有关系。  第二个输出解释: p是A类的指针,其寻址空间大小跟A类对象空间大小一致。

      当把b的对象地址赋予其的时候。因为其寻址空间 上面已经说明。在其寻址fun2时候,发现其实虚函数,虚函数是运行时候加载的。此时编译器

      根据其真实对象的虚函数来选择调用。这是编译器的约定,故而寻址到b的虚函数进行调用。

       此时的 p->fun1(); 因为其寻址空间限制,调用的还是A的 fun1。

     

          【有待验证】 题外: 上面的 B *p = &a;  的话 会出现什么结果呢?    解释: 此时p的寻址空间 就是 B对象的空间大小,此时把a对象地址赋予p时候,因为p寻址区间>a对象的内存空间。 会造成p在访问时候出现无效地址的访问,会造成内存错误,一般程序里面出现内存崩溃等情况 就这样。

       【真心期待路过的老鸟或者有兴趣的朋友留言沟通,指正,谢谢】

       延伸: 【

    B *p = (B *)&a;

    ptr->fun1();

    ptr->fun2();

    问这两调用的输出结果。这是一个用子类的指针去指向一个强制转换为子类地址的基类对象。结果,这两句调用的输出结果是B1,A2。

    并不是很理解这种用法,从原理上来解释,由于B是子类指针,虽然被赋予了基类对象地址,但是ptr->foo()在调用的时候,由于地址偏移量固定,偏移量是子类对象的偏移量,于是即使在指向了一个基类对象的情况下,还是调用到了子类的函数,虽然可能从始到终都没有子类对象的实例化出现。

    而ptr->fuu()的调用,可能还是因为多态性的原因,由于指向的是一个基类对象,通过虚函数列表的引用,找到了基类中foo()函数的地址,因此调用了基类的函数。由此可见多态性的强大,可以适应各种变化,不论指针是基类的还是子类的,都能找到正确的实现方法。】

  • 相关阅读:
    linq to sql 扩展方法
    跨线程的安全更新控件
    WinForm程序启动控制台窗口Console
    Winfrom巧用Using设置鼠标为WaitCursor
    在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。
    基于Token的身份验证——JWT(转)
    jwt算法
    session问题总既然(深入理解)&Token问题理解&sso单点登陆理解实现
    1.spring boot要求最低jdk1.8,平安默认1.6问题,-》安装JDK1.8 2.maven 3.3.3要求最低jdk1.7->安装jdk 1.8
    批量插入删除
  • 原文地址:https://www.cnblogs.com/minggeqiuzhi/p/3837263.html
Copyright © 2011-2022 走看看