2013-02-22 21 views
1

如果你在VS2010看<streambuf>頭文件,你會看到這個成員函數的定義爲什麼basic_streambuf :: pubseekoff()不是純虛函數?

pos_type pubseekoff(off_type _Off, ios_base::seekdir _Way, 
       ios_base::openmode _Mode = ios_base::in | ios_base::out) 
{ // change position by _Off, according to _Way, _Mode 
    return (seekoff(_Off, _Way, _Mode)); 
} 

其中seekoff是一個虛函數,這是在派生類basic_filebufbasic_stringbuf覆蓋和什麼也不做在基類basic_streambuf如可以看到下面:

virtual pos_type seekoff(off_type, ios_base::seekdir, 
         ios_base::openmode = ios_base::in | ios_base::out) 
{ // change position by offset, according to way and mode 
    return (streampos(_BADOFF)); 
} 

我找不到的_BADOFF定義,但它可能-1。但這真的不重要。此函數也不會調用pubseekoff,因爲類basic_streambuf是一個抽象類(其構造函數受保護)。

還要注意,gcc編譯器使用相同的技術。爲什麼兩個編譯器不得不求助於seekoff()成員函數,而不是簡單地將pubseekoff聲明爲basic_streambuf中的純虛函數,並將其定義在派生類basic_filebufbasic_stringbuf的每一箇中?

+0

可能是因爲標準規定呢? – PlasmaHH 2013-02-22 13:46:19

回答

3

出於同樣的原因,你通常不會使虛擬函數 公開。公共函數定義了一個接口,如果基類需要強制執行接口,則基類需要能夠捕獲它們。也有例外,當涉及控制 的倒置時,但在大多數情況下,您不需要公開虛擬 函數。如果你這樣做,你將如何插入前後條件 檢查? (見 http://www.gotw.ca/publications/mill18.htm,例如。)

+0

「...並且基類需要能夠捕獲它們,如果它想強制執行那個接口」。我不知道你在說什麼。 – 2013-02-23 01:01:00

+0

@ user1577873基類爲每個函數定義合同,包括事前和事後條件。爲了強制執行前置和後置條件,基類必須能夠在調用虛函數之前和之後插入代碼。它必須能夠「捕獲」呼叫,而不是直接將呼叫傳遞給派生類。 – 2013-02-24 18:24:23

+0

+1我認爲我現在已經擁有了一切。很好的答案。 TKS – 2013-02-24 22:52:17