2013-01-16 26 views
29

它是使用一個命名空間的靜態類好或好做法?例如:在C++中使用名稱空間代替靜態類?

namespace MyStaticFunctions { 
    void doSomething(); 
} 

對戰:

class MyStaticFunctions { 
    static void doSomething(); 
} 
+0

我喜歡「外部」,因爲只有C++可以在OOP中做這樣的事情;)也適用於C或Objective C兼容性。 – 9dan

+3

*「將命名空間用作靜態類是好還是不錯的做法」* - 事實上,這比實踐中的第二種選擇要好得多。如果你需要一個*「模板命名空間」*或者想讓一個完整的命名空間成爲另一個類的朋友(儘管這也可能是有問題的),後者只是首選的(或者更確切地說是需要的)。 –

回答

34

有沒有這樣的事情C++中的「靜態類」,所以從一個C++點你不使用它「作爲一個靜態類」,你使用它「爲命名空間」。使用命名空間將功能組合在一起當然是可以接受的做法。

這是給你,但是,你要多大的羣體是。 C++庫在整個公共接口中使用單個命名空間並不罕見。這可能會作爲一個驚喜的人誰是用來(比方說)的Java,其中類經常被用來組的靜態方法一起使用更小的數字。既然C++在這裏第一,你可以說Java正在使用類作爲名稱空間。

因此,在C++中,你往往不會看到類似java.util.Collectionsjava.lang.Math類,全靜態成員。如果你想在C++中使用這樣的函數組,可以使用名稱空間。

這個異常(在C++中並不總是存在一個特殊情況?)是類似std::numeric_limits<T>這樣的特徵類型,其中模板參數使該類執行某些命名空間無法做的事情。你可以定義一個名稱空間numeric_limits,其中包含功能模板max<T>(),min<T>()等,但它不是很好。首先,它將事物分組的方式略有不同,類型T顯示爲「降低層次結構」。其次,它不會完成特徵類型所做的所有事情,因爲沒有可以讓您定義值numeric_limits::digits<T>的「對象模板」。

我不知道C#以及足夠的靜態類存在的實際用途發表評論,但據我所知它只是限於沒有非靜態成員的一類,所以它是類似於Java類。

+1

+1另一種情況是,如果你想讓一個完整的命名空間成爲另一個類的朋友,那麼*「靜態類」*可能會派上用場(儘管這樣的設計可能首先是有問題的,但是有時候可以緩解很多)。 –

+4

_namespaces_更好的另一種情況。如果你要在函數中使用更多這種功能,你可以使用'使用命名空間MyStaticFunctions' – balki

4

這要看情況。

邏輯相關的類中的方法?如果是這樣,請將其設爲成員,否則將其放置在命名空間中。

功能上,它們是相同的,但有更多的代碼比功能,對不對?例如,考慮返回類的名稱的方法:

struct MyClass 
{ 
    static std::string getName() { return "MyClass"; } 
} 

你可以明顯地放置方法外,在namespace,並得到相同的結果,但它在邏輯上屬於類。

+1

這是什麼意思「與課程邏輯相關」? –

+0

@AndyT:好吧,它的邏輯與班級的邏輯密切相關。 –

21

在C++中,由於Koenig的查找(又名參數相關查找),實際上鼓勵您在語言級別使用namespace而不是僅包含static方法的class

例子:

namespace geometry { 
    struct Point { int x, y; }; 

    double distance_from_center(Point const& p) { 
     return sqrt(p.x * p.x + p.y + p.y); 
    } 
} // namespace geometry 

int main() { 
    geometry::Point const p{3, 4}; // must qualify 

    std::cout << distance_from_center(p) << "\n"; // not qualified 
} 

如果distance_from_center寫成一個static方法在class,則需要每次都明確限定它。

+1

我從來不知道這個!然而被明確會使它更具可讀性 – balki

+1

@balki:更可讀或​​更混亂?它總是一個很好的平衡。對於Java/C#開發人員來說,這可能有點令人眼花繚亂,但它在C++中是慣用的,所以沒有問題。此外,在通用代碼(模板)中,它更容易。 –

8

這對我來說是艱難的和有趣的問題個人,所以決定分享我的愚見

考慮到「靜態」類(僅限靜態成員)和命名空間之間的區別:

  1. 命名空間可以分散在多個文件中:額外的靈活性,但應慎重使用。
  2. 一個命名空間提供了參數依賴查找(see Matthieu M. answer):有用
  3. 「靜態」類可以有訪問修飾符,可以形成一個層次的具體情況:我認爲私有成員在類接口聲明,可見它的客戶是一個C++功能更多地是由技術而非邏輯原因決定的。我沒有看到私有靜態成員的任何好處。受保護的成員爲「靜態」層次結構?從未見過。
  4. 「靜態」類可以是一個「模板」,除了模板成員:看Steve Jessop's answer一個很好的例子,從STL

但從維修點,有時你決定做一個類「靜態「(像一個單身人士),但後來需求改變了,你需要多個實例。 「靜態」類比命名空間更容易轉換。

最後,回答你的問題:

如果你並不需要「靜態」類或命名空間的特殊功能,使用你喜歡什麼更多:)

+0

現在我非常想在一個只有靜態成員的類中爲受保護的成員使用它。也許某種類似CRTP的情況,一個類自然與派生類有特殊關係? –

相關問題