#include
#include
using namespace std;
class
a
int
getdata()
virtual
int
dogetdata()
};
class
b :
public
a
int
dogetdata()
};
class
c :
public
b
};
void
main()
5.1 程式執行後的輸出結果是什麼?
答案是:1 1 1 1 1 0 1 1
5.2 去掉 a 類中 dogetdata() 函式的 virtual 修飾,程式執行後的輸出結果是什麼?
答案是:0 0 0 0 1 0 1 1
說說我對這個題目的理解。
首先我們從物件的角度來看一下。
先看 main() 函式中構造 c 物件的語句: ?
1c c(10);
這句產生下面的效果:
c.m_data = 10;((b)c).m_data = 1;((a)c).m_data = 0;
為什麼呢?
c c(10);
這行**,定義了 c 物件,但實際上記憶體中有三個物件:
class c
的例項物件,即 c 由於 c 是 b 的派生類,會產生乙個 class b 例項物件,即 (b)c 由於 b 是 a 的派生類,會產生乙個 a 例項物件,即 (a)c
每個物件都有 m_data 成員變數, 根據繼承關係,子類覆蓋父類的同名成員(變數、函式), c 物件中實際上有三個同名的 m_data 變數,你通過不同的身份去看,會看到不同的 m_data 。 c
物件生成時,呼叫 b 、a 類的建構函式,對 b 、 a 初始化,結果就是: c
物件的 m_data = 10; ((b)c) 物件的 m_data = 1; ((a)c) 物件的 m_data = 0.
這就是我們一開始給出的效果。
明白了物件的關係和 m_data 成員的值。咱們再來看 getdata() 函式。
getdata()
函式是 class a 的乙個普通方法,根據繼承關係, b 、 c 類都可以訪問 getdata() 方法,因為 b 、 c 沒有重寫 getdata() ,所以通過 b 、 c 的物件訪問 getdata() ,訪問的都是 a 的 getdata() 方法。
在 getdata() 中,呼叫了 dogetdata() ,注意了,這是個虛函式!如果 a 的後裔重寫了 dogetdata() 函式,那麼這裡實際上會呼叫到繼承關係上處於最底層的那個類的 dogetdata() 函式,這就是虛函式和多型的概念。如你所見, b 重寫了 dogetdata() 函式,所以當你呼叫 c.getdata() , b 的 dogetdata() 會被呼叫, ((b)c).m_data 被返回。其實在 qt 中,這種用法比比皆是。
好啦,下面分析 main() 函式的輸出結果。
dogetdata()
帶 virtual 關鍵字
c.a::getdata() / c.getdata() / c.b::getdata() / c.c::getdata()
這些語句,都是呼叫 a::getdata() ,最終都呼叫 ((b)c).dogetdata(), 就是b::dogetdata() ,訪問的是 b 的物件,它的 m_data = 1 ,所以 dogetdata() 返回 1 ,最終 getdata() 返回 1 。 c
類沒有定義 dogetdata() 函式,c.dogetdata() 等同於 ((b)c).dogetdata() , 訪問的是 b 的物件,它的 m_data = 1 ,所以 c.dogetdata() 結果是 1 。
c.a::dogetdata()
,類域作用符限定了呼叫 a::dogetdata(),訪問 a 的物件,返回 ((a)c).m_data = 0 。
c.b::dogetdata() / c.c::dogetdata()
最終都是訪問 b 物件的 dogetdata() 方法, 返回都是 1 。
所以 dogetdata() 帶 virtual 關鍵字,程式輸出 1 1 1 1 1 0 1 1 。
去掉 dogetdata() 的 virtual 關鍵字
因為 getdata() 是 a 類的方法,而 dogetdata() 不是虛函式, a 類的 getdata() 內呼叫的 dogetdata() 方法只可能是 a 的物件的方法,((a)c).m_data = 0 ,所以前四個cout結果都是 0 。
c.dogetdata()
,c 的物件內沒有實現這個函式,呼叫父類的,即 b 的物件的 dogetdata() 方法,訪問的 m_data 是 ((b)c) 物件的,是 1 。
c.a::dogetdata()
,呼叫 a 的方法,訪問 a 的物件 ((a)c).m_data ,結果是 0 。
c.b::dogetdata() / c.c::dogetdata()
,呼叫 b 的方法,訪問 b 的物件 ((b)c).m_data ,結果為 1 。
所以,最終結果是:0 0 0 0 1 0 1 1
一道難住精英們的應聘題
招聘考場上的一道怪題難住了所有應聘的精英們 18 81 6 6 6 1 就這麼看似簡單的兩道算術題,任憑這些碩士 博士們用盡怎樣高深的運算,最後得出的結論是 無解。考場內所有人都交上了空白的考卷。這時,老總笑吟吟地走了進來。他說,我們想找的人,就是 從無解中找到答案的人 他先給大家講了乙個本企業發展...
這個夏天的我
這個夏天裡約奧運會,這個夏天人生中經歷第一次考驗,跪著走完自己選的路。這個夏天我有許多不一樣的感受 在學校和實驗室的朋友一起努力,感受清貧和阻力,還有便是即將成為乙個學長的體驗。不知為什麼,我發現自己似乎越來越會裝深沉,經常一副長者的口吻,不過大抵我也是不甘的吧,希望他們會有乙個比較好的大學生活,至...
我恨錢這個東西
哎!為什麼我人生總是感嘆呢?每當我鬱悶的時候我總是回來這裡寫點什麼。這難道真的能釋放出心中的壓力嗎?轉眼我快25了,但是我的心智發展卻遠遠跟不上我的年齡。我反覆的想啊想,反覆的算啊算 其實是我自己不敢面對自己而已。人總是生活在自己覺的最滿意的時候,卻往往一直不敢面對現實。貧窮是一種財富 這種財富來的...