C++类继承时的作用域嵌套,破解C++继承的一切秘密
類(lèi)其實(shí)也是一種作用域,每個(gè)類(lèi)都會(huì)定義它自己的作用域,在這個(gè)作用域內(nèi)我們?cè)俣x類(lèi)的成員,這一點(diǎn)已在《類(lèi)其實(shí)也是一種作用域》中講到。當(dāng)存在繼承關(guān)系時(shí),派生類(lèi)的作用域嵌套在基類(lèi)的作用域之內(nèi),如果一個(gè)名字在派生類(lèi)的作用域內(nèi)無(wú)法找到,編譯器會(huì)繼續(xù)到外層的基類(lèi)作用域中查找該名字的定義。
換句話(huà)說(shuō),作用域能夠彼此包含,被包含(或者說(shuō)被嵌套)的作用域稱(chēng)為內(nèi)層作用域(inner scope),包含著別的作用域的作用域稱(chēng)為外層作用域(outer scope)。一旦在外層作用域中聲明(或者定義)了某個(gè)名字,那么它所嵌套著的所有內(nèi)層作用域中都能訪(fǎng)問(wèn)這個(gè)名字。同時(shí),允許在內(nèi)層作用域中重新定義外層作用域中已有的名字。
假設(shè) Base 是基類(lèi),Derived 是派生類(lèi),那么它們的作用域的嵌套關(guān)系如下圖所示
派生類(lèi)的作用域位于基類(lèi)作用域之內(nèi)這一事實(shí)可能有點(diǎn)出人意料,畢竟在我們的代碼中派生類(lèi)和基類(lèi)的定義是相互分離的。不過(guò)也恰恰因?yàn)轭?lèi)作用域有這種繼承嵌套的關(guān)系,所以派生類(lèi)才能像使用自己的成員一樣來(lái)使用基類(lèi)的成員。
運(yùn)行結(jié)果:
c.biancheng.net
20
本例中,B 繼承自 A,C繼承自 B,它們作用域的嵌套關(guān)系如下圖所示:
obj 是 C 類(lèi)的對(duì)象,通過(guò) obj 訪(fǎng)問(wèn)成員變量 n 時(shí),在 C 類(lèi)的作用域中就能夠找到了 n 這個(gè)名字。雖然 A 類(lèi)和 B 類(lèi)都有名字 n,但編譯器不會(huì)到它們的作用域中查找,所以是不可見(jiàn)的,也即派生類(lèi)中的 n 遮蔽了基類(lèi)中的 n。
通過(guò) obj 訪(fǎng)問(wèn)成員函數(shù) func() 時(shí),在 C 類(lèi)的作用域中沒(méi)有找到 func 這個(gè)名字,編譯器繼續(xù)到 B 類(lèi)的作用域(外層作用域)中查找,仍然沒(méi)有找到,再繼續(xù)到 A 類(lèi)的作用域中查找,結(jié)果就發(fā)現(xiàn)了 func 這個(gè)名字,于是查找結(jié)束,編譯器決定調(diào)用 A 類(lèi)作用域中的 func() 函數(shù)。
這個(gè)過(guò)程叫做名字查找(name lookup),也就是在作用域鏈中尋找與所用名字最匹配的聲明(或定義)的過(guò)程。
總結(jié)
以上是生活随笔為你收集整理的C++类继承时的作用域嵌套,破解C++继承的一切秘密的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: C++继承时的名字遮蔽(二)
- 下一篇: C++继承时的对象内存位置(一)