C++ 继承多态问题

重载关系:

  不能在基类和派生类相同函数名,不同参数列表谈重载,重载必须是相同作用域下的一组函数才能构成重载。

隐藏关系:

    在继承关系中,派生类和基类的同名成员会被派生类隐藏,这个隐藏是指隐藏的作用域的隐藏,派生类只能调用自己的同名方法,若要调用基类同名方法要添加作用域。

派生类给基类赋值  这个是被允许的,而基类无法给派生类赋值,  基类的指针可以指向派生类,但是派生类的指针不能指向基类。

动态绑定和静态绑定:

当一个基类指针指向一个派生类时,基类指针调用某个方法,若基类中这个方法是普通方法,则就是静态绑定 call+函数地址编译时期确定,若这个是一个虚函数,则发生动态绑定,call +ecx 寄存器,只有运行的时候才能确定调用的函数。

覆盖/重写关系:

派生类对基类的虚函数进行重写,会在虚函数表中覆盖虚函数地址。

   如果一个类里面定义了虚函数,那么编译阶段,编译器会给这个类产生唯一的vftable虚函数表,虚函数表主要存储的是RTTi指针和虚函数地址,当程序运行时,虚函数表会被加载到.rodata段

  如果一个类里面有虚函数,那么这个类定义的对象在运行的时候,内存开始会有一个虚函数指针vfptr,指向这个唯一的虚函数表,

 一个类里面的虚函数个数不会影响对象内存的大小,只影响虚函数表的大小。

 如果派生类中的某个方法,和基类中的某个方法,方法名相同,返回值相同,参数列表相同,当基类是个virtual,则派生类中同名方法会自动处理成virtual.

一个基类指针指向派生类, A *p =&b;   若基类A中没有虚函数,则*p识别的是编译的时候类型,即*p<=> A,  若基类A有虚函数,*p 识别的是运行时候的类型  *p<=> B 这个类型。

哪些函数不能实现成虚函数?

虚函数依赖: 要能产生函数地址,存放在vftable (内联函数不行)

                  依赖对象,需要先去访问对象的vfptr 才能访问vftable,所以必须要有对象存在。

                  

构造函数:构造函数才开始构造对象,因此不能是虚函数,构造函数中所有调用的虚函数,都不会发生动态绑定。

              静态成员方法不能是虚函数,因为静态方法不依赖对象调用

析构函数:基类析构函数要实现成虚函数,不然基类的指针指向堆上派生类对象,当delete时,发生了静态绑定,导致派生类的析构无法析构,因此要将基类的析构函数实现成虚函数,delete 发送动态绑定,防止内存泄漏。

如何理解多态:静态的多态:模版,函数重载   动态多态:基类指针指向哪个派生类,就会调用该派生类的同名覆盖方法。

                  

猜你喜欢

转载自www.cnblogs.com/lc-bk/p/12408745.html
今日推荐