欢迎光临散文网 会员登陆 & 注册

Effective C++ 第三十三条 Avoid hiding inherited names.

2023-02-03 05:12 作者:九思519  | 我要投稿

避免遮掩继承而来的名称

变量声明的位置有很多,从作用域大小来说,从大到小分别是 global、namespace、base class、derived class、function。你在 function 使用变量 x,如果在 function 中没有声明 x,那么编译器会去 derived class 寻找,如果还没有就去 base 寻找,接着便是 namespace、global。如果最后还是没找到才会报错。

fun1 是 pure virtual,fun2 是 impure virtual,fun3 是 non-virtual,使用一个 derived 来继承 base

你可以在 fun4 中调用 fun2、fun3 等,虽然在 derived 中并没有,编译器会自动去 base 去寻找。

讲到这里,都很好理解,这类似于就近原则,但是接下里的可能有点不适应

如果 base 中有重载版本的函数呢?在 derived 中实现了 fun1(void),但是一旦你在 derived 中重写这个函数,derived 域会遮盖掉 base 域的内容,比如此时你无法在 derived 内调用 fun1(int),但是你可以调用 fun3(void) 和 fun3(double),因为你没有在 derived 里重写 fun3.这就导致一个可能让你不舒服的点,就是你只想重载 base 中的 fun1(void),但还是想接着使用 base 中的 fun1(int).这个时候你就需要使用 using 。

加上这句 using base::fun1,你就可以只重载 base 中的 fun1(void),接着使用 base 中的 fun1(int) 了。

这里又有一个新的问题,就是你并不想继承所有的 fun1,比如

你现在只想要 base::fun1(void) 和 base::fun1(int),如果你使用 using ,你就会得到四个 fun1,这不是你想要的。这个时候就需要用到转角函数(forwarding functions)。

这样就可以实现对 base 中 fun1(int)的调用又对外隐藏了其他重载。

总结:

  • derived classes 内名称会遮掩 base classes 内的名称。在 public 继承下从来没有人希望如此。

  • 为了让被遮掩的名称重见天日,可使用 using 声明式或转角函数(forwarding functions)。


Effective C++ 第三十三条 Avoid hiding inherited names.的评论 (共 条)

分享到微博请遵守国家法律