2009-07-16 114 views
1

我有一個重載操作< <試圖使它像這樣重載運算符采用函數指針作爲參數,如何取回函數指針的參數

mystream<<hex<<10; 

我重載方法

mytream& operator<<(ios_base& (*m) ios_base&) 
工作

只要遇到十六進制,就會被調用,導致在方法中傳遞的參數是一個類型與十六進制類似的函數指針,或者像dec,oct等其他輸出操縱符。

我有兩個問題

1)我如何獲取十六進制將上操作的參數,在這個例子中10

2)我怎麼了< <運營商被要求知道十六進制和像十月和DEC沒有其他機械手功能

感謝

回答

7

1)己未在參數10 <<運營商關聯操作左到右的,這意味着您的代碼是相同的:

(mystream<<hex)<<10; 

所以你的過載必須返回一個物體,當10被移入時,以十六進制打印(或者如果不打印,則在某處寫入數據)。正如大家所說,這是通過在流對象本身中保存標誌完成的,然後返回*this。使用原因標誌正是因爲「10」尚未提供,因爲第二個<<尚未評估。第一個<<操作員調用不能打印任何東西 - 只需要在第二個調用時做好準備。

2)十六進制是一個函數。它可以與其它功能比較:

ostream &operator<<(ostream &s, ios_base& (*m)(ios_base &)) { 
    if (m == hex) { 
    } else if (m == oct) { 
    } else if (m == dec) { 
    } 
} 

除非你通常不希望這樣做,你想要的默認行爲,這是一樣的東西:

ostream &operator<<(ostream &s, ios_base& (*m)(ios_base &)) { 
    return m(s); 
} 

(我可能是錯的我從來沒有看過實現,但總體思路是操作員調​​用操縱器函數,而操縱器(名稱中的線索)操縱流。

std::hex在其參數上設置std::ios::hex格式標誌。然後在operator<<(int)覆蓋中,如果有覆蓋,請通過調用flags()來檢查格式標誌。

3)帶參數的機械手也是函數,但它們的返回類型沒有指定,這意味着它的實現。看看我的gcc iomanip標題,setw返回_Setw,setprecision返回_Setprecision,依此類推。 The Apache library does it differently,更像無參數操縱器。你可以使用參數化操縱器做的唯一事情就是將它們應用於一個帶有operator<<的iostream,它們沒有定義的成員函數或它們自己的操作符。

所以就像hex,處理setw你應該從std::ios_base繼承,依賴於你的庫提供的operator<<實施,那麼當你來格式化數據,檢查自己的寬度,精度等,使用width()precision()等,功能ios_base

也就是說,如果出於某種奇怪的原因,你需要攔截的標準operator<<這些操縱,你很可能bodge東西一起,沿着這些線路:

template <typename SManip> 
mystream &operator<<(mystream &s, SManip m) { 
    stringstream ss; 
    // set the state of ss to match that of s 
    ss.width(s.width()); 
    ss.precision(s.precision()); 
    // etc 
    ss << m; 
    // set the state of s to match that of ss 
    s.width(ss.width()); 
    s.precision(ss.precision()); 
    // etc 
    return s; 
} 

我不認爲這是一個bodge,雖然。你並不是真的應該干涉流操縱器,只要讓你的基類做工作,並查找結果。

0

operator<<被稱爲與hexoctdec,在您的mystream對象中設置一個標誌。當用號碼調用operator<<時,請檢查是否設置了這些標誌中的任何一個。如果是這樣,將數字轉換爲十六進制/八進制/十進制並顯示它。

+0

這是一個遞歸的答案「當operator <<以十六進制或十進制或十進制調用時,在mystream對象中設置一個標誌」時,第二個問題是如何知道調用了哪些函數? 「 」將數字轉換爲十六進制/八進制/十進制並顯示它。「如何在我的重載操作符函數中獲取該數字,即第一個問題 – Kazoom 2009-07-16 19:27:26

+1

您應該在* another *重載操作符函數中獲取數字,其中一個會得到int – 2009-07-16 20:38:32

0

在回答你的第二個問題時,參數m是一個指向操縱器函數的指針。您可以檢查它是否爲空,然後調用該函數,傳遞*this。如Zifre所示,hex()與在傳遞的流對象中設置標誌一樣簡單。然後在處理整數時,檢查流對象中的標誌是否已設置,並相應地輸出。

這是標準庫如何實現其操縱器功能。

+1

爲什麼選擇down表決? – 2009-07-16 21:06:20

0

在您的示例中,十六進制操作(更改狀態)流,而不是以下參數。十六進制與其他< <調用沒有任何關係或任何關係。看看其他io操縱器是如何實現的,將會對清除問題有很長的路要走。