类的成员隐藏,覆盖与重载

C++令人迷惑的隐藏规则(转自林锐的《高质量c-c++编程》)

8.2.2 令人迷惑的隐藏规则

  本来仅仅区别重载与覆盖并不算困难,但是C++的隐藏规则使问题复杂性陡然增加。这里“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:

(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。

(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。

因为我也是一个在学习路上的小白,如果有错误的地方,恳请指正,谢谢!


第一个例子:非虚函数的隐藏与重载

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <string>

using namespace std;

struct Base
{
	
	void func()
	{
		cout << "func()" << endl;
	}
	void func(int i) //这里的func是重载关系
	{
		cout << "func(int)" << endl;
	}
};

struct Derived : public  Base
{
	void func()
	{
		cout << "Derived::func()" << endl;//参数与基类某个函数一致,隐藏了基类中同名函数以及重载
	}
};
struct Derived2 : public  Base
{
	int func(double i)		//参数与基类任意成员函数都不一致,但同样隐藏了基类中同名函数以及重载
	{
		cout << "Derived2::func()" << endl;	
		return 0;
	}
};
int main() {


	Derived d;
	Derived2 dd;

	d.func();        //调用的Derived::
	dd.func(1);      //调用的Derived2::func(int)
	//结论:如果是非虚函数,那么派生类和基类不管函数参数是否相同,派生类会隐藏基类成员函数
	return 0;
}

第二个例子:虚函数的隐藏、覆盖与重载

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <string>

using namespace std;

struct Base
{
	
	virtual void func()
	{
		cout << "func()" << endl;
	}
	void func(int i)                 //这里的func同样也是重载关系
	{
		cout << "func(int)" << endl;
	}
};

struct Derived : public  Base
{
	void func()                      //函数原型相同,默认是虚函数,这里是覆盖了从基类继承过来的func。
	{
		cout << "Derived::func()" << endl;//参数与基类某个函数一致,隐藏了基类中同名函数以及重载
	}
};
struct Derived2 : public  Base
{
	int func(double i)		//函数原型不同,隐藏了基类的func虚函数。
	{
		cout << "Derived2::func()" << endl;	
		return 0;
	}
};
int main() {


	Derived d;
	Derived2 dd;
	Base &b = d;

	//d.func(1);                    //错误,在Derived中找不到void func(int)这个函数
	d.func();                       //调用的Derived::func()
	//dd.func();                    //错误,在Derived2中找不到void func()这个函数
	dd.func(1);                     //调用的Derived2::func(double)
	
	//结论:如果是虚函数,派生类的虚函数和基类中同名函数函数原型相同的话,派生类虚函数会覆盖基类成员函数,同
	//时隐藏基类中的同名函数及其他重载
	//如果函数原型不同,会创建出一个新的成员函数(而不是覆盖),同时隐藏基类中的同名函数及其他重载

	return 0;
}

总结:除了覆盖继承而来的虚函数之外,派生类最好不要重用其他定义在基类中的名字

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值