如何在C ++类中定义编译时(静态)常量?

时间:2015-01-16 09:00:36

标签: c++ class const class-variables

我有一些常量只需要在编译时使用以简化代码,因此我不需要在运行时可用的实际变量。

传统上这样做的方式是使用#define NAME 123,但我想要一种类型安全的替代方案。

在课程之外你可以const int name = 123;工作正常,但似乎不可能把它放在课堂里。例如:

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

适用于Visual C ++,但不适用于GCC:

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编译器?

5 个答案:

答案 0 :(得分: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 :(得分:4)

我在C ++ 03中看到了两种可能的方法:

  1. 使用静态成员函数并依赖于内联:

    class Example {
        public:
            static double usPerSec() { return 1000000.0; }
    };
    double usOneMinute = 60 * Example::usPerSec();
    
  2. 使用静态数据成员并在常量折叠时退出(使用常量的值将在运行时计算):

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

答案 2 :(得分:2)

如果我是你,我会把它放在命名空间中:

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

答案 3 :(得分:1)

此代码适用于vc ++和gcc:

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

答案 4 :(得分:1)

你必须使它成为静态const,然后在课外给它值。不要在构造函数中执行此操作。你不必制作make实例

class Example {
public:
    static const double usPerSec;

};

double Example::usPerSec = 1000000.0;

现在您可以在任何地方使用它而无需创建任何类

的实例
double someVar = Example::usPerSec;