基类和派生类中存在同名函数时的调用选择

1. 背景

存在继承关系的两个类,基类中的方法A中调用了方法B,而父子类中均存在B方法,当通过子类对象调用A方法,或者 基类指针指向派生类对象,通过基类指针去调用A方法, 此时在A方法中调用的是父类还是子类中的B方法呢?

2. 示例说明

情况1:父类中B方法为普通函数,则调用的是父类中的B方法,示例代码:

#include <iostream>

class Base{
public:
    Base(std::string name):m_name(name) {};
    int get_age() {return 36;}
    void show_info(){
        //此时子类对象调用show_info调用的是父类中的get_age()方法
        std::cout<<m_name<<" 年龄:"<<get_age()<<std::endl; 
    }
private:
    std::string m_name{};
};

class Driver :public Base{
public:
    using Base::Base;   //继承了Base的构造函数
    int get_age(){
        return 26;
    }
};

int main(){
    Driver obj("ZhangSan");  //如果Driver中没有”using Base::Base;“,则无法这样构造Driver的obj
    obj.show_info();
    return 0;
}

输出结果:

 

原因:因为show_info所在的作用域是父类作用域,在编译的时候,链接到的是父类中的方法。

情况2:父类中B方法为虚函数,并且子类中重写了该方法,则调用的是子类中的B方法: 

父类中的get_age()方法修改如下,则执行结果为:

class Base{
public:
    Base(std::string name):m_name(name) {};
    virtual int get_age() {return 36;}
    void show_info(){
        //此时子类对象调用show_info调用的是父类中的get_age()方法
        std::cout<<m_name<<" 年龄:"<<get_age()<<std::endl; 
    }
private:
    std::string m_name{};
};

 

原因:因为B方法为虚函数,在子类对象内存空间中的虚函数指针所指向的虚函数表中,子类方法覆盖了父类中的方法。

 情况3:父类中B方法为虚函数,但子类中的没有重写该方法,则调用的是父类中的B方法: 

如将子类的get_age()方法屏蔽掉,则输出结果为:

class Driver :public Base{
public:
    using Base::Base;   //继承了Base的构造函数
    // int get_age(){
    //     return 26;
    // };
};

 

原因:虽然B方法为虚函数,但在子类对象内存空间中的虚函数指针所指向的虚函数表中,父类中的方法没有被覆盖掉。

  情况4:父类中B方法为纯虚函数,则调用的是子类中的B方法:

父类修改如下,执行结果为:

class Base{
public:
    Base(std::string name):m_name(name) {};
    virtual int get_age() = 0;
    void show_info(){
        //此时子类对象调用show_info调用的是父类中的get_age()方法
        std::cout<<m_name<<" 年龄:"<<get_age()<<std::endl; 
    }
private:
    std::string m_name{};
};

原因:同普通虚函数的原因一样,只不过父子类中只有一份实现, 并且子类必须要覆盖掉父类中的方法。

情况5:通过基类指针指向派生类对象,通过该基类指针调用B方法,各个以上4种情况的结果和原因与通过子类对象去调用B方法相同。因为方法A仅存在与基类中,虽然通过基类指针执行了派生类对象,但没有形成多态,遂与通过子类对象调用方法A的结果一样。

int main(){
    Base* obj = new Driver("ZhangSan");
    obj->show_info();
    return 0;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值