2015-01-16 98 views
5

我有一些常量,只需要在編譯時使用,以簡化代碼,所以我不需要在運行時可用的實際變量。如何在C++類中定義編譯時(靜態)常量?

傳統上這樣做的方式是#define NAME 123,但我想要一個類型安全的替代方案。

以外的類可以const int name = 123;哪些工作正常,但似乎不可能把它放在課堂上。例如這樣的:

class Example { 
    public: 
     const double usPerSec = 1000000.0; 
}; 
double usOneMinute = 60 * Tempo::usPerSec; 

工程用Visual C++,但不與海灣合作委員會的工作:

error: non-static const member ‘const double Example::usPerSec’, 
    can’t use default assignment operator 

您可以通過它的靜態修復它,但隨後的Visual C++抱怨:

error C2864: 'Example::usPerSec' : a static data member with an in-class 
    initializer must have non-volatile const integral type 
    type is 'const double' 

我猜這意味着VC++將只接受static const int

我想避免在構造函數中設置值,因爲然後我需要在運行時訪問該值的類的實例,而實際上我希望它在編譯時處理,就像#define一樣。

那麼如何在一個類中定義一個常量爲double,而不訴諸於全局或使用#define,這將在沒有該類的實例的情況下工作,並且可以與主要的C++ 03編譯器一起工作?

回答

10

的任何實例有積分和其他類型之間這裏的差異。對於整型你總是可以將它們定義爲const static成員在

struct Example 
{ 
    const static int name = 123; // added 'static' to code in text of question 
    const static unsigned usPerSec = 1000000; 
}; 

對於非整數類型,在你的例子,如double,情況就比較複雜了。自2011年(使用大多數編譯器編譯器選項std=c++11),你可以簡單地這樣做:

struct Example 
{ 
    constexpr static double usPerSec = 1000000.0; 
}; 

但用gcc,這

struct Example 
{ 
    const static double usPerSec = 1000000.0; 
}; 

也應該工作在C++ 03(這是一個GNU擴展)。

然而,在C++ 03的標準方法,其中也使用標準庫本身(例如在std::numeric_limits<>),是一個static成員函數

struct Example 
{ 
    static double usPerSec() { return 1000000.0; } 
}; 
+1

'+ 1'提到'std :: numeric_limits <>',我覺得這很有用。 – Angew

1

此代碼工作在兩個VC++和GCC:

class Example { 
public: 
    static const double usPerSec ; 
}; 
const double Example::usPerSec=10000.0; 
double usOneMinute = 60 * Example::usPerSec; 
4

我看到C++ 03兩種可能的方法:

  1. 使用靜態成員函數,依靠內聯:

    class Example { 
        public: 
         static double usPerSec() { return 1000000.0; } 
    }; 
    double usOneMinute = 60 * Example::usPerSec(); 
    
  2. 使用靜態數據成員並在常量摺疊上退出(使用常量的值將是comp貢獻在運行時):

    class Example { 
        public: 
         static const double usPerSec; 
    }; 
    double usOneMinute = 60 * Example::usPerSec; 
    
    // Somewhere in one .cpp 
    const double Example::usPerSec = 1000000.0; 
    
+0

如果您在庫中使用它並使用MSVC++進行編譯,第二個選項會提供未解析的外部。不得不在DLL中導出符號對於一個在庫之外通常不會顯示的編譯時常量而言肯定是矯枉過正的! – Malvineous

1

你必須讓它靜態常量,然後給它的價值之外類。不要在構造函數中做。您不必製作實例

class Example { 
public: 
    static const double usPerSec; 

};現在

double Example::usPerSec = 1000000.0; 

,你可以在任何地方使用它,而使得類

double someVar = Example::usPerSec; 
2

如果我是你,我會放它在一個命名空間中:

namespace MyExampleNamespace { 
    const double usPerSec = 1000000.0; 
} 
double usOneMinute = 60 * MyExampleNamespace::usPerSec;