c++虚函数:父类与子类虚函数的形参不一样会发生什么?

摘抄,部分关于虚函数的总结

  1. 如果以一个基础类指针指向一个衍生类对象(派生类对象),那么经由该指针只能访问基础类定义的函数(静态联编)
  2. 如果以一个衍生类指针指向一个基础类对象,必须先做强制转型动作(explicit cast),这种做法很危险,也不符合语法习惯,在程序设计上也会给程序员带来困扰。(一般不会这么去定义)
  3. 如果基础类和衍生类定义了相同名称的成员函数(包括参数相同),那么通过对象指针调用成员函数时,到底调用那个函数要根据指针的原型来确定,而不是根据指针实际指向的对象类型确定。
  4. 虚函数就是为了对“如果你以一个基础类指针指向一个衍生类对象,那么通过该指针,你只能访问基础类定义的成员函数”这条规则反其道而行之的设计。

关于纯虚拟函数:
virtual void myfunc ( ) =0;

  1. 纯虚拟函数不许定义其具体动作,它的存在只是为了在衍生类钟被重新定义。
  2. 只要是拥有纯虚拟函数的类,就是抽象类,它们是不能够被实例化的(只能被继承)。
  3. 如果一个继承类没有改写父类中的纯虚函数,那么他也是抽象类,也不能被实例化。
  4. 抽象类不能被实例化,不过我们可以拥有指向抽象类的指针,以便于操纵各个衍生类。
  5. 虚拟函数衍生下去仍然是虚拟函数,而且还可以省略掉关键字“virtual”。

下面探讨父类和子类虚函数形参不同时的情况

总结:

当父类和子类的虚函数同名不同参数的时候,就和非虚的同名函数一样。父类指针指向子类对象的时候,只能访问父类同名函数;而子类指针指向子类函数,只能访问子类同名函数。


1. 父类和子类的虚函数名相同,形参也相同

这是正常情况,子类对象会生成虚函数列表,在虚函数列表中用子类新定义的虚函数代替父类同名、同参数的虚函数。

2.虚函数名相同,父类无形参,子类有形参

1)使用父类指针调用子类对象的虚函数方法
  • 带形参调用,会显示找不到函数;

  • 不带形参调用,会得到父类虚函数的运行结果。

    说明:

    • a.子类虚函数并没有在虚函数列表中代替父类的虚函数;
    • b.父类指针指向子类的对象,也仅只能调用父类的虚函数(这和非虚函数一样)。

对于b的题外话:当子类多继承了多个父类后,若每个父类都有一个虚函数表,子类就会在内存中按顺序保存每一个父类的虚函数列表,并把自己的虚函数指针放在按顺序排放的第一个虚函数列表中,如下图所示。(图片来自于鸟恋旧林XD
在图片来自

2)使用子类指针调用子类对象
  • 带参数调用,会显示子类虚函数的调用结果;

  • 不带参数调用,会显示找不到匹配的函数。

    说明
    子类的虚函数列表中没有替代父类同名不同参数的虚函数指针,但是也没有保留,而是将其隐藏了?可能是这样,待下一步探索。

参考:
1.对虚函数列表用的比较透彻: C++ 虚函数 获取C++虚表地址和虚函数地址
2.实例介绍 虚函数与默认实参
3.C++多态,虚函数作用及底层实现原理

下面的没有用
—————————————————————————————————————

  1. 使用父类指针调用子类对象的虚函数方法

    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. 使用子类指针调用子类对象的虚函数方法

2.子类无形参,父类有形参

  1. 使用父类指针调用子类对象的虚函数方法
  2. 使用子类指针调用子类对象的虚函数方法
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页