Effective C++ 第三十三条 Avoid hiding inherited names.
避免遮掩继承而来的名称
变量声明的位置有很多,从作用域大小来说,从大到小分别是 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)。

