首页 > 代码库 > C++多态性的浅析

C++多态性的浅析

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

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

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

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

                 b新增的地址空间

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

 

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

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

 

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

    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()函数的地址,因此调用了基类的函数。由此可见多态性的强大,可以适应各种变化,不论指针是基类的还是子类的,都能找到正确的实现方法。】