C/C++ 被隐藏的父类函数

不知道大家有没有听说过函数隐藏

见字面意思就是函数被隐藏,那么为什么会被隐藏了?隐藏了又是什么概念呢?

下面将通过一个例子讲解!

例子是这样的:
有一个单身Boy类,他有三个重载play的成员方法,分别是:
void play()void play(string name)void play(string name1, string name2);
他还有一个子类PlayBoy类,子类中,重写了父类Boy类中的void play(string name1, string name2)方法!然后main方法中调用这些方法而产生的一系列问题!!!

问题一:子类对象无法访问父类的成员函数;
问题二:当子类没有重写父类的成员函数时,子类可以调用父类的成员函数;

我们先看代码:

#include <iostream>
#include <Windows.h>
#include <string>

using namespace std;

// 定义Boy类
class Boy {
public:

	// 父类的三个重载函数
	void play() {
		cout << "自己一个人玩!" << endl;
	}

	void play(string name) {
		cout << "我和" << name << "一起看电影!" << endl;
	}

	void play(string name1, string name2) {
		cout << "我和" << name1 << "、" << name2 << "一起做对人运动!" << endl;
	}
};

// 定义PlayBoy类继承与Boy类
class PlayBoy : public Boy {
public:
	// 子类中重写play(string name1, string name2)方法
	void play(string name1, string name2) {
		cout << "我和" << name1 << "、" << name2 << "一起吃鸡!" << endl;
	}
};



int main(void) {
	PlayBoy* boy = new PlayBoy;

	// 可以调用自己的成员方法
	boy->play("小明", "小红");

	// 调用不了父类的其他成员方法
	//boy->play("小明");
	//boy->play();

	system("pause");
	return 0;
}

运行结果是这样的:
在这里插入图片描述

然而如果我们调用父类的方法,就会提示报错!
在这里插入图片描述

然而,当我们吧子类的重写父类的play方法注释后,却没有报错,可以运行:
在这里插入图片描述
让我们来看看运行结果:
在这里插入图片描述
看,真的没问题,可以运行!!!

这是怎么回事呢???

其实,当子类重写父类的成员函数时,父类的成员函数对于子类对象来说,已经是隐藏的了,也就是在子类中已经没有父类的成员函数的存在了。

举一个例子:
一个公司,已经有了一套管理体系,而新的领导来报道后,如果他继续沿用这套旧的管理体系,那么对所有人都没有影响;如果新的领导要重写修改管理体系,那么旧的管理体系就已经完全没用了,只有新的管理体系在执行着!
转换为上面的代码也是一样的,如果子类继承父类后没有重写父类的成员函数的话,那么父类的成员函数,子类对象依旧可以调用;然而当子类重写父类的成员函数后,父类的成员函数对于子类就已经没用了,也就相当于被隐藏了!
这就是为什么子类重写父类的成员函数后就调用不了父类的成员函数了!

当然,以上只是针对父类的重载函数起作用,对于父类其他的函数还是可以正常调用的!
不懂的,请看下面总结!

例如,我们在父类中加上一个函数void getPlay(),那么,子类一样可以正常调用:

#include <iostream>
#include <Windows.h>
#include <string>

using namespace std;

// 定义Boy类
class Boy {
public:

	// 父类的三个重载函数
	void play() {
		cout << "自己一个人玩!" << endl;
	}

	void play(string name) {
		cout << "我和" << name << "一起看电影!" << endl;
	}

	void play(string name1, string name2) {
		cout << "我和" << name1 << "、" << name2 << "一起做对人运动!" << endl;
	}

	// 父类的其他函数
	void getPlay() {
		cout << "开黑一直爽,一直开黑一直爽!" << endl;
	}
};

// 定义PlayBoy类继承与Boy类
class PlayBoy : public Boy {
public:
	// 子类中重写play(string name1, string name2)方法
	void play(string name1, string name2) {
		cout << "我和" << name1 << "、" << name2 << "一起吃鸡!" << endl;
	}
};



int main(void) {
	PlayBoy* boy = new PlayBoy;
	//Boy* boy = new PlayBoy;

	boy->play("小明", "小红");

	// 可以正常调用,没有报错
	boy->getPlay();

	//boy->play("小明");
	//boy->play();

	system("pause");
	return 0;
}

运行结果:
在这里插入图片描述


好了,那么我们该如何解决以上遇到的问题呢?

有两个解决办法:
第一:使用父类指针指向子类对象:Boy* boy = new PlayBoy;
第二:调用父类函数时,使用强制类型转换:((Boy *)boy)->play("小明");

int main(void) {
	//PlayBoy* boy = new PlayBoy;

	/*
	 * 方法一: 使用父类指针指向子类对象
	 */
	Boy* boy = new PlayBoy;

	boy->play("小明", "小红");

	// 可以正常调用,没有报错
	//boy->getPlay();

	/*
	 * 方法二: 使用强制类型转换
	 */
	((Boy *)boy)->play("小明");
	((Boy*)boy)->play();

	system("pause");
	return 0;
}

运行结果:
在这里插入图片描述


总结:
子类实现某函数后,从父类继承的函数,只要函数名相同,无论是否同参,无论是否是虚函数,使用子类指针访问,只能访问到子类重写的函数,父类的同名函数都被隐藏;

使用父类指针访问:

  1. 对于虚函数:只能访问到子类重写的函数
  2. 非虚函数:只能访问到父类的函数
  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cpp_learners

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值