【问题标题】:How to define compile-time (static) constant inside a C++ class?如何在 C++ 类中定义编译时(静态)常量?
【发布时间】:2015-03-14 20:14:51
【问题描述】:

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

传统上,这是使用 #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 编译器?

【问题讨论】:

    标签: c++ class constants class-variables


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      这里的积分类型和其他类型是有区别的。对于整数类型,您始终可以将它们定义为 const static 成员,如

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

      对于非积分类型,例如double在您的示例中,情况更复杂。自2011年以来(使用大多数编译器使用Compiler Option @ 987654324),您可以简单地执行以下操作:

      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提及std::numeric_limits<>,我觉得这是一个有用的点。 span>
      【解决方案3】:

      您必须将其设为静态常量,然后在类外赋予它值。不要在构造函数中这样做。您不必制作实例

      class Example {
      public:
          static const double usPerSec;
      

      };

      double Example::usPerSec = 1000000.0;
      

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

      double someVar = Example::usPerSec;
      

      【讨论】:

        【解决方案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;
          

        【讨论】:

        • 如果您在库中使用第二个选项并使用 MSVC++ 编译,第二个选项会给出未解析的外部变量。必须在 DLL 中导出符号对于假定的编译时常量来说绝对是矫枉过正,通常在库之外是不可见的!
        【解决方案5】:

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

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

        【讨论】:

          猜你喜欢
          • 2013-04-11
          • 2016-07-14
          • 1970-01-01
          • 1970-01-01
          • 2015-04-03
          • 1970-01-01
          • 2011-02-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多