2013-07-28 46 views
-1

我已經看到幾個抽象類的例子,其中有一個朋友operator<<和一個虛擬的「print」成員函數,其中兩個聲明均位於protected部分。例如:抽象類中受保護的流操作符

class Function{ 
public: 
    virtual ~Function() {} 
    virtual double value(const double x) const = 0; 
    virtual Function* clone() const = 0; 
protected: 
    friend ostream& operator<<(ostream& os, Function& f); 
    virtual void print(ostream& os) const = 0; 
}; 

ostream& operator<<(ostream& os, Function& f){ 
    f.print(os); 
    return os; 
} 

我不明白爲什麼這是強制性的。有人可以解釋嗎?

謝謝!

+2

爲什麼*什麼*是強制性的? – juanchopanza

+0

請學會正確書寫**聲明......您沒有注意到[您的上一個問題](http://stackoverflow.com/questions/17907019/friend-declaration-in-protected-section)是否被編輯過? (鏈接:http://stackoverflow.com/posts/17907019/revisions)閱讀「decleration」讓我很難過:'( –

+0

好吧,我自己修復它...現在仍然有'operator <<'的參數'Function&f '應該是'const Function&f'(兩次),因爲打印'f'不應該修改它,但我不想觸摸代碼(實際上我剛剛注意到我添加了一個缺少';'後類的定義) –

回答

1

首先,您聲明friend函數/運算符的位置並不重要。它不是publicprotectedprivate。它只是一個friend函數/運算符,所以它可以訪問類的成員,而不管他們的訪問限制。所以流運營商不受保護。這是一個friend,這允許它訪問print()方法。

二,print方法應該可能是private。如果你想從更多的派生類中調用基類的print方法,那麼它將只適用於protected。但是該設計表明它是一個實現細節以實現ostream& operator<<

另一方面,如果您設計了自己的班級,以便print方法公開,那麼ostream& operator<<就不需要爲friend

+0

爲什麼'print'函數應該是私有的?由於它是'const',它不能使任何不變量失效,它沒有任何先決條件,也沒有你可能驗證的後置條件。實際上,可以通過公共接口通過'<<'訪問,我想不出有什麼可能的原因不會讓它成爲'public'。 –

+0

@JamesKanze我認爲它是實現輸出流運算符'<<'的一種方式。 ,我認爲在課堂的公共接口中不需要它。 – juanchopanza

0

這當然不是強制性的。其實我會爭辯說這是 糟糕的設計。

你把朋友聲明放在哪裏並不重要;訪問 spedifiers不適用於它。由於operator<<是公共接口的部分 ,不論你在何處聲明它的,它 更有意義的聲明它在類的公共區域, 因爲這其中誰不是從類派生的用戶將 找它。

關於print功能,我也可以沒有真正的 理由聲明它什麼,但公開的。鑑於大多數, 如果不是所有訪問它將通過朋友operator<<, 它可能沒有關係,但我不知道 宣佈它private獲得什麼。作爲一般規則,沒有任何東西是 通過聲明任何東西而獲得protected;這是非常罕見的使用 protected。在20世紀90年代中期,有人認爲你應該宣稱其功能protected而不是public和 標準庫的部分仍然反映這種約定。 但我認爲,今天的共識是,1)如果此規則適用 ,虛函數應該是private,不 protected; 2)這條規則並不總是在 情況下一個const函數的應用—,像print,實際上從來沒有 適用。

相關問題