2011-10-06 26 views
4

在處理C++代碼時,我確實遇到了一些困難。假設我有一個方法做X,Y,然後是Z.現在我想介紹另一種應該做X,Y',Z的方法。如果這是簡單的舊C代碼,我會然後用通用代碼生成函數X()和Z(),聲明它們以便編譯器現在可以根據需要內聯它們,因爲沒有代碼可以從這個「模塊」中調用它們。那是API的一部分,然後,該方法看起來像在C++中將常用塊提取到函數中

int M(args) { 
    X(foo); // that could e.g. be "check args are valid". 
    /* here comes M-specific code */ 
    Z(bar); // that could e.g. be "update_state" 
} 

int M2(args) { 
    X(foo); 
    /* here comes M2-specific code */ 
    Z(bar); 
} 

現在,如果我做同樣的在C++中,X()和Z()不再具有訪問類的保護/私有成員。在.h和.cc文件之間進行交換以聲明這些「helper」X()和Z(),因爲我繼續進行代碼寫作時不知何故試圖讓我只是複製/粘貼通用代碼,所以我傾向於複製而不是類,在.h中更接近(java)接口的東西 - 幾乎沒有成員變量 - 然後在.cc文件中的class塊中包含變量,API方法和「幫助程序」方法,它們從「接口」。然而,我懷疑這是C++的好習慣,所以我很想知道其他人在這種情況下做了什麼。

+0

有趣的問題。我總是發現C++中的類聲明在抽象和信息隱藏方面表現不佳。 –

+0

頭部中的類不需要是具有實現的類。您可以使用抽象基類或pImpl慣用法將兩者分開。那麼實現可以完全在.cc中。 –

+0

@Alan筆畫:抽象基類或pimpl習語是繁瑣的方法,當我只是想隱藏一個私人成員的視圖。 –

回答

3

如果XZ正在做與類相關的東西,然後使它們成爲類的成員函數(如果沒有,那麼沒有問題,因爲它們的實現可以很容易地放在其他地方,公開視圖)。

如果他們不應該是該類的公共接口的一部分,使他們private

如果它困擾你,他們的函數簽名顯示在類定義中,那麼有幾種方法來重構你的代碼,以這種方式實現細節不公開。

一種常用的方法是使用Pimpl idiom

另一種方法是隻在公開API中暴露(抽象)接口,並從視圖中隱藏實現類。這並不總是可行的,但如果是這樣,它可能非常有效。

+0

額外的「私人東西」類與那些私人成員和函數直接定義在.cc ...有趣的。該班級無法訪問例如ApiClass的受保護成員,但我想我可以使用一些朋友聲明來避免成員之間的這種劃分。 – PypeBros

+0

不確定我喜歡pimpl如何強迫我使用數據 - > xxx爲每個數據成員,儘管> _ < – PypeBros

+0

@sylvainulg:這不是很漂亮,不。但它達到了預期的效果。正如其他地方所說的,C++並沒有真正提供隱藏實現細節的便捷方式,因此,無論使用哪種技術,都不會像將功能內置到語言中那樣漂亮/方便。 –

0

如果需要,您可以將XZ功能移動到您班級的私人成員函數中,並用inline修飾符標記它們。這將允許訪問私人成員,同時難以從課外訪問。

0

,我認爲你是錯的概念:

  • 如果X()Z()有共同的代碼,這是一個設計改進。重構它們。
  • 如果M1(args)工作正常,你爲什麼改變它?一旦你重構了X()Z(),你可以在其他方法中使用它們。只需使用新的X()Z()創建M2(args),並在新的Y()方法中加上新功能。
+0

恐怕你錯了(或者我含糊地問)。 X()和Z()不共享公共代碼。它們是M()中存在的代碼,現在在M()和M2()中都需要,因此我想將它們作爲函數進行提升。 – PypeBros

0

您可以進行功能分爲:

  1. 使它們的類的私有成員。
  2. 或者您可以將它們放置在實現文件中的匿名名稱空間內。

對於選項#2你將不能訪問類的私有成員,雖然這是一個大問題,它可以在所有通過(只)所需的參數得到緩解,並且要麼返回一個值或使用輸出參數(指針或引用)。

1

如果我理解你正確的想要實現的是爲多個函數M()只寫兩個函數X()和Z()一次。像其他評論一樣,建議讓它們的成員函數標記爲內聯。

此外,以實現X()和Z()的成員函數我會用,你有一個函數M()這樣的

class ClassTest 
{ 
    private: 
    void X(); 
    void Y(); 

    Alogrithm* m_algorithm; 

    public: 
    void M(); 
    void setAlgorithm(Alogrithm* a) { m_algorithm = a; } 
} 

void ClassTest::M() 
{ 
    X();  
    m_algorithm->execute();  
    Z(); 
} 

此策略模式消除了對第二個功能M2的需求( )。您只需要爲m_algorithm設置一個setter,它是實現原始函數Y()的小對象。這樣算法甚至可以改變運行時間。

+0

有趣的替代方案,但在我的情況下引入這種副作用並不好。 – PypeBros