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 
#include 
#include 

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;
}

运行结果是这样的:
C/C++ 被隐藏的父类函数_第1张图片

然而如果我们调用父类的方法,就会提示报错!
C/C++ 被隐藏的父类函数_第2张图片

然而,当我们吧子类的重写父类的play方法注释后,却没有报错,可以运行:
C/C++ 被隐藏的父类函数_第3张图片
让我们来看看运行结果:
C/C++ 被隐藏的父类函数_第4张图片
看,真的没问题,可以运行!!!

这是怎么回事呢???

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

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

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

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

#include 
#include 
#include 

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;
}

运行结果:
C/C++ 被隐藏的父类函数_第5张图片


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

有两个解决办法:
第一:使用父类指针指向子类对象: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;
}

运行结果:
C/C++ 被隐藏的父类函数_第6张图片


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

使用父类指针访问:

  1. 对于虚函数:只能访问到子类重写的函数
  2. 非虚函数:只能访问到父类的函数

你可能感兴趣的:(报错积累)