函数:父类与子类虚函数的形参不一样会发生什么?"/>
c++虚函数:父类与子类虚函数的形参不一样会发生什么?
摘抄,部分关于虚函数的总结
- 如果以一个基础类指针指向一个衍生类对象(派生类对象),那么经由该指针只能访问基础类定义的函数(静态联编)
- 如果以一个衍生类指针指向一个基础类对象,必须先做强制转型动作(explicit cast),这种做法很危险,也不符合语法习惯,在程序设计上也会给程序员带来困扰。(一般不会这么去定义)
- 如果基础类和衍生类定义了相同名称的成员函数(包括参数相同),那么通过对象指针调用成员函数时,到底调用那个函数要根据指针的原型来确定,而不是根据指针实际指向的对象类型确定。
- 虚函数就是为了对“如果你以一个基础类指针指向一个衍生类对象,那么通过该指针,你只能访问基础类定义的成员函数”这条规则反其道而行之的设计。
关于纯虚拟函数:
virtual void myfunc ( ) =0;
- 纯虚拟函数不许定义其具体动作,它的存在只是为了在衍生类钟被重新定义。
- 只要是拥有纯虚拟函数的类,就是抽象类,它们是不能够被实例化的(只能被继承)。
- 如果一个继承类没有改写父类中的纯虚函数,那么他也是抽象类,也不能被实例化。
- 抽象类不能被实例化,不过我们可以拥有指向抽象类的指针,以便于操纵各个衍生类。
- 虚拟函数衍生下去仍然是虚拟函数,而且还可以省略掉关键字“virtual”。
下面探讨父类和子类虚函数形参不同时的情况
总结:
当父类和子类的虚函数同名不同参数的时候,就和非虚的同名函数一样。父类指针指向子类对象的时候,只能访问父类同名函数;而子类指针指向子类函数,只能访问子类同名函数。
1. 父类和子类的虚函数名相同,形参也相同
这是正常情况,子类对象会生成虚函数列表,在虚函数列表中用子类新定义的虚函数代替父类同名、同参数的虚函数。
2.虚函数名相同,父类无形参,子类有形参
1)使用父类指针调用子类对象的虚函数方法
-
带形参调用,会显示找不到函数;
-
不带形参调用,会得到父类虚函数的运行结果。
说明:
- a.子类虚函数并没有在虚函数列表中代替父类的虚函数;
- b.父类指针指向子类的对象,也仅只能调用父类的虚函数(这和非虚函数一样)。
对于b的题外话:当子类多继承了多个父类后,若每个父类都有一个虚函数表,子类就会在内存中按顺序保存每一个父类的虚函数列表,并把自己的虚函数指针放在按顺序排放的第一个虚函数列表中,如下图所示。(图片来自于鸟恋旧林XD)
2)使用子类指针调用子类对象
-
带参数调用,会显示子类虚函数的调用结果;
-
不带参数调用,会显示找不到匹配的函数。
说明
子类的虚函数列表中没有替代父类同名不同参数的虚函数指针,但是也没有保留,而是将其隐藏了?可能是这样,待下一步探索。
参考:
1.对虚函数列表用的比较透彻: C++ 虚函数 获取C++虚表地址和虚函数地址
2.实例介绍 虚函数与默认实参
3.C++多态,虚函数作用及底层实现原理
下面的没有用
—————————————————————————————————————
-
使用父类指针调用子类对象的虚函数方法
a.使用形参:
class super{ public:virtual void disp(){cout<<"base"<<endl;}}; class sub: public super {public:virtual void disp(int i){cout<<"sub"<<i<<endl;} }; int main() {sub suba;super *supera=&suba;supera->disp(1);return 0; }
下图为计算结果,可以看出,此时调用的是父类中的方法。也就是说虚函数列表中父类的虚函数没有被
b.不使用形参:
-
使用子类指针调用子类对象的虚函数方法
2.子类无形参,父类有形参
- 使用父类指针调用子类对象的虚函数方法
- 使用子类指针调用子类对象的虚函数方法
更多推荐
c++虚函数:父类与子类虚函数的形参不一样会发生什么?
发布评论