c++ 避免遮掩继承而来的名称

参考 effective c++ 条款33

我觉得看完书中的 总结一下
感觉就是在讲作用域的规则,在继承中作用域的规则
编译器查找同名变量函数的规则

double num = 5;			//global 变量

int main()
{
	int num = 3;		//local 变量

	cout << num << endl;
}

运行结果大家都知道是 3
编译器在局部函数 main 内 首先寻找 名字为 num 的变量
如果找不到 就去外层作用域继续找 还找不到就找有没有 global

c++ 名称遮掩规则 所做的唯一事件就是遮掩名称
这个名称变量的类型是否相同并不重要 上面就是 int num 遮掩了 double num

上面比较直观简单 向下递增难度讲讲

继承中的遮掩名称
在这里插入图片描述

看一下这个继承结构

基类 实现了3个 函数

  • 纯虚函数 mf1()
  • 虚函数 mf2()
  • 普通函数mf3()

派生类 重新实现了 纯虚函数 mf1()
实现了自己的函数 mf4()

mf4() 中 又调用了 mf2()

当编译器执行到 mf4 中时 看到 mf2 要知道他是啥东西

  • 先在 local 函数 mf4() 作用域内找有没有 mf2()
  • 在去Derived 中 找有没有 mf2()
  • 在去Derived 的父类中 继续找有没有 mf2()
  • . . . . . .
  • 继续向外层找 找不到就报错了 说没有 mf2()
继续增加难度 继承中出现重载

在这里插入图片描述

仔细看上面的规则

	int  x = 1;
	Derived d;

	d.mf1();
	d.mf1(x);
	d.mf2();
	d.mf3();
	d.mf3(x);

这段代码执行会发生什么呢?

在这里插入图片描述
在这里插入图片描述

报错了 说明 d.mf1(int) 和 d.mf3(double) 继承失败了

什么原因呢?

编译器 不管你的函数是不是虚函数 是不是重载
因为编译器在查找名字时,并没有“为重载而走的很远”,C++的确是支持重载的,编译器在发现函数重载时,会去寻找相同函数名中最为匹配的一个函数(从形参个数,形参类型两个方面考虑,与返回值没有关系),如果大家的匹配程度都差不多,那么编译器会报歧义的错。

首先找 作用域内 mf1() 和 mf3 有没有同名的 如果有 那么就不会去上层找了
也就是说 重载的带参的 base mf1(int) 和 mf3(double) 被 derived class 内的 mf1() 和 mf3() 给 遮掩掉了

我现在就要调用父类重载的函数 现在有两种办法解决这个问题
1.采用 using 声明

在这里插入图片描述
在这里插入图片描述
用了using,实际上是告诉编译器,把父类的那个函数也纳入第一批查找范围里面,这样就能发现匹配得更好的重载函数了。
这样就不报错了 当查找 mf1 时 编译器发现两个就会按照重载函数的规则执行。

2.采用 inline 转交函数

在这里插入图片描述
在这里插入图片描述
也重载一个 带 int 的 mf1(int x) 函数
然后内部实现时 调用基类的 函数 就完成了 我们想要的的效果了

注意:

1.派生类的名称会遮掩基类的名称,在public继承下从来没有人希望如此
2.可以用 using 声明 或者 转交函数 解决这个问题
发布了194 篇原创文章 · 获赞 443 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/weixin_42837024/article/details/105118874