簡體   English   中英

優先將非成員非朋友功能發送給成員函數

[英]Preferring non-member non-friend functions to member functions

這個題目標題取自Scott Meyers的Effective C ++ 3rd Edition中第23項的標題。 他使用以下代碼:

class WebBrowser {
public:
    void clearCache();
    void clearHistory();
    void removeCookies();

    //This is the function in question.
    void clearEverything();
};

//Alternative non-member implementation of clearEverything() member function.
void clearBrowser(WebBrowser& wb) {
    wb.clearCache();
    wb.clearHistory();
    wb.removeCookies();
};

雖然聲明下面的替代非成員非友元函數比成員函數clearEverything()更適合封裝。 我想部分想法是,如果提供訪問的成員函數較少,則訪問WebBrowser的內部成員數據的方法較少。

如果你接受這個並使這種外部非朋友功能的功能,你會把它們放在哪里? 函數仍然與類緊密耦合,但它們將不再是類的一部分。 將它們放在類的相同CPP文件中,在庫中的另一個文件中,或者什么?

我主要是來自C#背景,而且我從來沒有對所有成為課堂成員的渴望擺脫那種渴望,所以這讓我感到有些困惑(雖然聽起來可能很傻)。

通常,您可以將它們放在關聯的命名空間中。 這(在某種程度上)與C#中的擴展方法有相同的功能。

問題是在C#中,如果你想制作一些靜態函數,它們必須在一個類中,這是荒謬的,因為根本沒有OO - 例如,Math類。 在C ++中,您可以使用正確的工具來完成這項工作 - 命名空間。

所以, clearEverything都是一種非常必要的便利方法。 但是由你來決定它是否合適。

這里的哲學是類定義應盡可能保持最小,並且只提供一種方法來完成某些事情。 這降低了單元測試的復雜性,交換替代實現的整個類所涉及的難度,以及可能需要被子類覆蓋的函數數量。

通常,您不應該只使用一系列其他公共成員函數的公共成員函數。 如果你這樣做,它可能意味着:1)你的公共接口太詳細/細粒度或其他不合適,被調用的函數應該是私有的,或者2)該函數應該真正在類外部。

汽車類比:喇叭通常與踩剎車一起使用,但添加一個新的踏板/按鈕同時做兩件事是愚蠢的。 Car.brake()Car.honk()是由Driver執行的功能。 然而,如果Car.leftHeadLampOn()Car.rightHeadLampOn()是兩個獨立的公共方法,它可能是過度細粒度控制的一個例子,設計者應重新考慮給DriverCar.lightsOn()開關。

在瀏覽器示例中,我傾向於同意Scott Meyers的觀點,即它不應該是成員函數。 但是,將它放在瀏覽器命名空間中也可能不合適。 也許最好讓它成為控制Web瀏覽器的東西的成員,例如GUI事件處理程序的一部分。 MVC專家隨時可以從這里接管。

我做了很多。 我總是把它們放在與其他類成員函數相同的.cpp中。 我不認為有任何二進制大小開銷取決於你放置它們的位置。 (除非你把它放在標題中:P)

如果你想沿着這條路走下去, clearEverything clearEverything的clearEverything應該放在標題(聲明)和類的實現中 - 因為它們是緊密耦合的,似乎是放置它們的最佳位置。

但是我傾向於將它們作為類的一部分 - 因為將來你可能有其他事情要清除,或者可能有更好或更快的實現來實現clearEverything例如刪除數據庫並重新創建表

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM