【C++】多态 ⑥ ( 函数重定义涉及的问题 - 子类覆盖父类函数名 )

2023-10-31 14:17:48 浏览数 (1)

一、函数重定义涉及的问题

1、执行出错的代码

错误代码示例 :

代码语言:javascript复制
#include "iostream"
using namespace std;

// 父类
class Parent {
public:
	void fun(int a, int b, int c)
	{
		cout << "执行 父类 void fun(int a, int b, int c) 函数" << endl;
	}

	void fun(int a, int b)
	{
		cout << "执行 父类 void fun(int a, int b) 函数" << endl;
	}

	void fun(int a)
	{
		cout << "执行 父类 void fun(int a) 函数" << endl;
	}
};

// 子类
class Child : public Parent {
public:
	void fun(int a, int b)
	{
		cout << "执行 子类 void fun(int a, int b) 函数" << endl;
	}

	void fun(int a)
	{
		cout << "执行 子类 void fun(int a) 函数" << endl;
	}
};


int main() {

	Child c;
	c.fun(1, 2, 3);

	// 控制台暂停 , 按任意键继续向后执行
	system("pause");

	return 0;
}

报错信息 :

已启动生成… 1>------ 已启动生成: 项目: HelloWorld, 配置: Debug Win32 ------ 1>Test.cpp 1>D:02_Project06_Visual_StudioHelloWorldHelloWorldTest.cpp(41,15): error C2661: “Child::fun”: 没有重载函数接受 3 个参数 1>已完成生成项目“HelloWorld.vcxproj”的操作 - 失败。 ========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========

2、代码分析

在 Parent 父类 中 , 定义了如下 3 个函数 ,

代码语言:javascript复制
	void fun(int a, int b, int c)
	void fun(int a, int b)
	void fun(int a)

在 Child 子类中 , 重定义了上述 3 个函数中的 2 个函数 ,

代码语言:javascript复制
	void fun(int a, int b)
	void fun(int a)

注意 : 是重定义 , 不是重写 ; 重写 需要 为 父类 函数添加 virtual 关键字修饰 , 会有多态效果 ;

重定义 时 , 子类 会 覆盖 父类 的 函数名称 ;

执行

代码语言:javascript复制
	Child c;
	c.fun(1, 2, 3);

代码 , 尝试调用 父类的 3 个参数的 fun 函数 , 出现错误 ,

报错 : error C2661: “Child::fun”: 没有重载函数接受 3 个参数 ;

该错误是编译阶段报的错误 , 编译根本通不过 ;

3、错误原因分析 - 函数重定义问题 : 子类覆盖父类函数名

错误原因分析 : 函数重定义 带来的问题 , 子类覆盖父类函数名 ;

函数重定义的函数名称覆盖问题 : C 编译器 发现 Child c 对象要调用 void fun(int a, int b, int c) 函数 , 子类中已经存在 fun 函数了 , 子类 会 覆盖 父类的函数名 , C 编译器只会在 子类查找 该函数 , 不会去父类 查找 ;

子类查找函数 : C 编译器 在 子类中找到了 void fun(int a, int b) 和 void fun(int a) 两个函数 , 没有找到 3 个参数的函数 , 此时 C 编译器会报错 :

代码语言:javascript复制
error C2661: “Child::fun”: 没有重载函数接受 3 个参数 ; 

4、正确调用函数的方法

在这种情况下 , 由于子类 重定义了部分 父类的重载函数 , 导致 父类的 函数名被覆盖 , 此时需要使用 域操作符 访问父类 被覆盖的函数 ;

代码语言:javascript复制
	Child c;
	c.Parent::fun(1, 2, 3);

代码示例 :

代码语言:javascript复制
#include "iostream"
using namespace std;

// 父类
class Parent {
public:
	void fun(int a, int b, int c)
	{
		cout << "执行 父类 void fun(int a, int b, int c) 函数" << endl;
	}

	void fun(int a, int b)
	{
		cout << "执行 父类 void fun(int a, int b) 函数" << endl;
	}

	void fun(int a)
	{
		cout << "执行 父类 void fun(int a) 函数" << endl;
	}
};

// 子类
class Child : public Parent {
public:
	void fun(int a, int b)
	{
		cout << "执行 子类 void fun(int a, int b) 函数" << endl;
	}

	void fun(int a)
	{
		cout << "执行 子类 void fun(int a) 函数" << endl;
	}
};


int main() {

	Child c;
	c.Parent::fun(1, 2, 3);

	// 控制台暂停 , 按任意键继续向后执行
	system("pause");

	return 0;
}

执行结果 :

代码语言:javascript复制
执行 父类 void fun(int a, int b, int c) 函数
Press any key to continue . . .

0 人点赞