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

避免遮掩繼承而來(lái)的名稱
變量聲明的位置有很多,從作用域大小來(lái)說(shuō),從大到小分別是 global、namespace、base class、derived class、function。你在 function 使用變量 x,如果在 function 中沒(méi)有聲明 x,那么編譯器會(huì)去 derived class 尋找,如果還沒(méi)有就去 base 尋找,接著便是 namespace、global。如果最后還是沒(méi)找到才會(huì)報(bào)錯(cuò)。
fun1 是 pure virtual,fun2 是 impure virtual,fun3 是 non-virtual,使用一個(gè) derived 來(lái)繼承 base
你可以在 fun4 中調(diào)用 fun2、fun3 等,雖然在 derived 中并沒(méi)有,編譯器會(huì)自動(dòng)去 base 去尋找。
講到這里,都很好理解,這類似于就近原則,但是接下里的可能有點(diǎn)不適應(yīng)
如果 base 中有重載版本的函數(shù)呢?在 derived 中實(shí)現(xiàn)了 fun1(void),但是一旦你在 derived 中重寫這個(gè)函數(shù),derived 域會(huì)遮蓋掉 base 域的內(nèi)容,比如此時(shí)你無(wú)法在 derived 內(nèi)調(diào)用 fun1(int),但是你可以調(diào)用 fun3(void) 和 fun3(double),因?yàn)槟銢](méi)有在 derived 里重寫 fun3.這就導(dǎo)致一個(gè)可能讓你不舒服的點(diǎn),就是你只想重載 base 中的 fun1(void),但還是想接著使用 base 中的 fun1(int).這個(gè)時(shí)候你就需要使用 using 。
加上這句 using base::fun1,你就可以只重載 base 中的 fun1(void),接著使用 base 中的 fun1(int) 了。
這里又有一個(gè)新的問(wèn)題,就是你并不想繼承所有的 fun1,比如
你現(xiàn)在只想要 base::fun1(void) 和 base::fun1(int),如果你使用 using ,你就會(huì)得到四個(gè) fun1,這不是你想要的。這個(gè)時(shí)候就需要用到轉(zhuǎn)角函數(shù)(forwarding functions)。
這樣就可以實(shí)現(xiàn)對(duì) base 中 fun1(int)的調(diào)用又對(duì)外隱藏了其他重載。
總結(jié):
derived classes 內(nèi)名稱會(huì)遮掩 base classes 內(nèi)的名稱。在 public 繼承下從來(lái)沒(méi)有人希望如此。
為了讓被遮掩的名稱重見天日,可使用 using 聲明式或轉(zhuǎn)角函數(shù)(forwarding functions)。