2010-09-30 30 views
1

可能重複:
static const vs #define在整個應用程序中使用常量。使用的#define或可變

您好所有,在C++中,定義整個應用程序中使用的常數,你是什麼人通常的做法?

#define WINDOWS_HEIGHT 1024 

const int WINDOWS_HEIGHT = 1024; 

感謝。

+1

調試器將無法對宏執行任何操作。 – 2010-09-30 03:34:27

+2

@Martin,這不一定是真的。 gdb支持[宏擴展](http://www.delorie。COM/GNU /文檔/ GDB/gdb_70.html)。 – 2010-09-30 03:37:41

+2

參見[ static const vs #define ](http://stackoverflow.com/questions/1637332/static-const-vs-define)。 – 2010-09-30 03:41:08

回答

7

利弊一切,取決於用途:

  • 枚舉
    • 唯一可能的整數值很好地處理
    • 強類型
    • 正常範圍的/標識符衝突的問題,但是到了足夠大的帶符號或無符號整數大小,您無法控制(在C++ 03中)
    • 不能接收地址
    • 更強的使用限制(例如遞增 - template <typename T> void f(T t) { cout << ++t; }將不會編譯)
    • 每個常量的類型取自封閉的枚舉,因此template <typename T> void f(T)從不同的枚舉中傳遞相同的數值時會得到不同的實例化,所有這些都與任何實際的f(int)實例不同。
    • 即使使用typeof,也不能期望numeric_limits提供有用的洞察
    • 枚舉的類型名可能出現在RTTI,編譯器消息等的不同位置。 - 可能是有用的,可能混淆
  • consts很好
  • 強,單一的,用戶指定的類型
  • 一個定義規則併發症
  • 定義處理
    • 正確作用域/標識符衝突問題
      • 「全局」範圍/更容易出現衝突的用法,這可能會產生難以解決的編譯問題和意外的運行時結果,而不是理智的錯誤消息;減輕這一要求:
        • 長,模糊的和/或集中協調標識符,並獲得他們不能從隱含受益匹配中/電流/凱尼格-查到的命名空間,命名空間別名等
        • 使用所有的大寫字母通常是必需的,並且保留用於預處理器定義(企業級預處理器使用保持可管理的重要準則,以及可以期待遵循哪些第三方庫),觀察其中意味着現有常量或枚舉的遷移定義涉及變化在大寫(因此影響客戶端代碼)。 (就個人而言,我利用枚舉的第一個字母,但不consts,所以我會在這裏反正被擊中 - 也許時間來重新考慮。)
      • 更多的編譯時間操作成爲可能:字符串字面串聯,字串(以其大小)
        • 不足之處是給出#define X "x"和一些客戶使用阿拉"pre" X "post",你就麻煩了,如果你想要或需要做X運行時可改變的變量,而不是一個常數,而這種轉變是從const char*容易或const std::string,因爲它們已經強制用戶併入級聯操作。
      • 不能使用sizeof直接在所定義的數值常數
      • 無類型(GCC不警告如果與無符號)
      • 一些編譯器/鏈接器/調試器鏈可以不存在,則識別符,所以你將被縮減爲查看「幻數」(字符串,無論...)
      • 不能接受地址
      • 在#define爲上下文的上下文中,替換值不需要是合法的(或離散的)創建,因爲它在每個使用點進行評估,因此您可以引用未聲明的對象,取決於「實現」 「T被預先包括,創建可用於初始化數組‘常量’如{ 1, 2 },或#define MICROSECONDS *1E-6等(絕對不推薦這個!)
      • __FILE____LINE__一些特殊的東西可以摻入宏替換

    作爲一般規則,我用consts並考慮將其用於一般用途最專業的選擇(儘管該有的都有了一個簡單呼籲這個老懶惰的程序員)。

  • 2

    我的投票是'namespace scope extern const'變量在一個ane中定義的只有一個翻譯單元。命名空間範圍'const'變量具有內部鏈接。

    8

    如何使用enum而不用擔心鏈接?

    +0

    除了連接問題外,訪問速度應該更快,並且在某些情況下可以給編譯器提供一些有用的提示:'如果some_const'恰好爲0,'x^= some_const;'將不會產生任何代碼。 – ruslik 2010-09-30 03:36:36

    +0

    enumerator是它的大小是實現定義的。不知道這是在C++中更改0x – Chubsdad 2010-09-30 04:00:03

    +0

    @Chubsdad:在C++中,您可以通過指定初始值設定項來控制枚舉類型。在C中,類型是'int'。 – 2010-09-30 04:20:39

    3

    嗯,取決於。對於整型常量enum效果很好。例如:

    struct Constants { 
        enum { 
         WindowHeight = 8, 
         WindowWidth = 8, 
         // ... 
        }; 
    }; 
    ... 
    int h = Constants::WindowHeight; 
    
    3

    使用常量整數;它將顯示在調試器中#define值可能不存在的地方。或者使用枚舉;那也可以。

    2

    我使用命名空間範圍extern const。

    1

    使用define可以簡單地用您的代碼替換所有出現的值。常量全局變量幾乎相同,只有類型可以明確定義。這幾乎是唯一的區別。

    就我個人而言,我寧願使用一個定義,只是出於品味。

    但是,我認爲沒有什麼區別。

    相關問題