2011-05-09 74 views
3

可能重複:
Static members class vs. normal c-like interface爲什麼要在類中定義常量而不是命名空間?

我在看大人物代碼,並有一類定義如下幾十個常量:

// header file 

class Defines 
{ 
public: 
    static const int Val1; 
    static const int ValN; 
    static const char* String1; 
    static const char* StringN; 
... 
} 

// .CPP 
const char* Defines::String1 = "some value" 
etc. 

是有一些原因做這些事情,而不是使用名稱空間呢? 超過其他

--------- ----------編輯一個有優勢/劣勢

對不起,我明明應該指出這一點因爲沒有人從班級名稱中推斷出來 - 這是「定義」。即這些常量不與某個特定的類相關聯,因此創建了一個專門用於保存常量而不是其他任何東西的類,這就是Defines所包含的所有類。

我的問題是不是你爲什麼應該把常量在一個特定的類,問題是有沒有在收集數十人在一起,並把它們一類其唯一目的是收集在一起的常量,而不是任何值將它們一起收集到一個名稱空間中,或者只是將它們收集在專門用於該目的的頭文件中。

(項目中沒有當前存在的名稱空間,因此在答案中提到的污染名稱空間的潛在問題不是)

-----第32次編輯-----------

和跟進的問題--- 拼勁 爲const char *定義:: StringN = 「someValue中」

在.h文件低效與將其放置在.cpp文件

回答

0

一般來說,沒有理由使用這種方式。我曾看到它認爲,如果「常量集合」演變成一個具體的對象,以這種方式開始,過渡變得更容易。在實踐中,我從未見過這種情況發生。它只是隱藏了意圖,並可能使用私有構造函數來動搖代碼。

有人可能會說類可以使用模板,而命名空間不能。所以,如果Defines是一類像下面這樣只會工作:

template<typename T> int function() { 
    return T::x + T::y; 
} 
//later 
cout << function<Defines>() << function<OtherDefines>() << endl; 

在大多數情況下,這可能會更好地工作了重新設計,特別是如果你所有的只是「常量」是不是真的。有時候,這可能會派上用場。

有時,它也可以打擊依賴參數的查找。簡而言之,允許編譯器根據傳遞給函數的參數將可擴展函數名稱擴展到不同的名稱空間。這不會擴展到一個類的靜態函數。但是,這更適用於一般情況,除了常量集合外,「靜態類」還包括嵌套類型和函數。

爲什麼人們這樣做會有所不同。有些來自不能用這種方式的語言,其他人只是不知道更好。

2

因爲那些常數可能與該類緊密耦合。 IE可能類的成員將這些常量作爲參數或返回它們。也許他們唯一有意義的地方在於這個類的接口,所以把它們放在一個單獨的名字空間中是沒有意義的,因爲它們只對那個類很重要。

1

的幾個原因:

  1. 你不和潛在的隨機常量塞滿您的命名空間。
  2. 通過在類和常量本身中包含它們以及它們的關聯類,您將爲它們增添意義。

如果我要定義一個名爲NAME的全局/名稱空間常量,那麼它與什麼關聯?如果我將它添加到類本身中,那麼您不得不引用類名,這會增加用法的含義並使代碼更具可讀性並且不易出錯。

當然,這可以被濫用。你可以放錯常量。你可以不正確地把真正的全局常量放在特定的類中。在這兩種情況下,你都可以給出壞名字。

+0

但是,1)沒有先前存在的名稱空間混亂。2)正如「定義」這個類的名字所表明的那樣,它們是在一個沒有別的東西的類中,即。與他們相關的特定特定類別無關。 – Gruntcakes 2011-05-09 21:56:29

+0

它仍然增加了含義,因爲你知道它來自哪裏(因此,如果你需要的話,在哪裏尋找它),它集中了分佈,而不是讓一堆命名空間全局變量生存在隨機文件中。它集中了位置,類似於將本地化詳細信息存儲到單個資源文件中(至少對於給定的單元)。 – pickypg 2011-05-09 22:00:02

+0

對不起,但我沒有看到收集類中常量與將它們收集在名稱空間中的區別。命名空間同樣集中了它們的分佈,並且你知道在哪裏尋找它們,所以爲什麼使用類比命名空間更好?我的問題不是爲什麼把它們收集在一起,我的問題是是否將它們收集在一個類中或命名空間中,如果在一個類中,爲什麼一個類在命名空間上,如果命名空間,爲什麼命名空間在類上,如果它沒有區別,那麼這也是一個答案。 – Gruntcakes 2011-05-09 22:07:34

0

對於大多數情況,給它們儘可能小的範圍是有意義的。在這種情況下,它不是一個知名度問題,但在清晰度

如果您在方法中看到String1,您不知道它來自哪裏。如果你看到Defines::String1,你可以說「好吧,這是來自Defines類的一個變量,讓我去那裏看看它是什麼以及它應該是什麼」。查看一個類比查看可能跨多個源文件分佈的整個名稱空間要好得多。顯然,如果變量是在一個類中,因爲它主要用於該類,那麼毫無疑問,這就是它應該在的地方。 :D

2

沒有理由像這樣做;就像沒有真正的理由使用class Defines { public: ... };而不是struct Defines { ... };。也許編寫代碼的人以前一直在用不支持命名空間中的命名空間/全局變量的語言編寫,或者認爲這看起來比整個外部語句和命名空間更「整潔」。

但是,如果您打算將這些常量中的一些設置爲私有的,然後只允許訪問一些函數/類,那麼對此有一些實際用途。然而,從外觀來看,情況並非如此,將它改爲命名空間是有道理的 - 那樣的話,可以使用using Defines::constant;等。

對第一次編輯的響應:全局命名空間也是一個命名空間,它比其他命名空間更污染,因爲它更容易泄漏到其中。從這個意義上講,最好把變量放在一個類中,但仍然不如將它們放在它們自己的名字空間中。

對第二個編輯的響應:const char* Defines::StringN = "Somevalue";在標題中會導致常量被定義多次,程序將無法鏈接。但是,如果您預先設定了extern,並將該定義放在.cpp文件中,則一切都會好起來,並且不應該有任何性能損失。

相關問題