C++常量的最佳实践

Ben*_*ker 22 c++ constants

我有一大堆常量,我想在我的代码的不同部分访问,但我希望能够轻松访问整个:

static const bool doX = true;
static const bool doY = false;
static const int maxNumX = 5;
Run Code Online (Sandbox Code Playgroud)

等等

所以我创建了一个名为"constants.h"的文件,并将它们全部放在那里,并将#included包含在任何需要知道常量的文件中.

问题是,这对于编译时来说很糟糕,因为每次更改常量时,都必须重建constants.h引用的所有文件.(另外,据我所知,因为它们是静态的,所以每次在新的.cpp中包含constants.h时,我都会在代码中生成doX/doY/maxNumX的副本,导致在编译时浪费千字节的空间EXE - 有没有办法看到这个?).

所以,我想要一个解决方案.如果可能的话,不是"仅在使用它们的文件中声明常量".

有什么建议?

Mat*_*lia 9

唯一的选择是制作常量extern并在另一个.cpp文件中定义它们,但是你将失去优化的可能性,因为编译器在编译每个.cpp`时将不知道它们具有什么值.

顺便说一句,不要担心大小增加:对于整数类型,您的常量可能直接在生成的机器代码中内联.

最后,这static不是必需的,因为默认情况下const全局变量是staticC++.


Mat*_* M. 8

我认为你的基本假设是关闭的.

您的其他标题通常是通过将哪些标题组合在一起来组织的.例如,一个类及其相关方法或两个类严重相互关联.

为什么要将所有常量分组到一个标题中?它没有任何意义.这"global.h"与包含每个单一依赖项的标题一样糟糕.

通常,常量用于特定上下文中.例如,枚举用作特定函数的标志:

class File {
public:
  enum class Mode {
    Read,
    Write,
    Append
  };

  File(std::string const& filename, Mode mode);

  // ...
};
Run Code Online (Sandbox Code Playgroud)

在这种情况下,这些常量与它们绑定的类(甚至在类中)之间存在于相同的头中是很自然的.

另一类常量是那些只渗透整个应用程序的常量.例如:

enum class Direction {
  Up,
  Down,
  Right,
  Left,
  Forward,
  Backward
};
Run Code Online (Sandbox Code Playgroud)

...在一个游戏中,你想要表达物体对他们所面对方向的移动.

在这种情况下,为这组特定的常量创建一个头文件很好.

如果你真的担心将这些文件组合在一起:

constants/
  Direction.hpp
  Sandwich.hpp
  State.hpp
Run Code Online (Sandbox Code Playgroud)

当你添加一个常量时,你会巧妙地回避重新编译整个应用程序的问题......但如果你需要,那么,你只付出一次成本,比你必须付出的错误设计更好和你的其余工作一起生活.


Luc*_*ore 7

您将它们声明为extern标题,并在实现文件中定义它们.

这样,当您想要更改它们的值时,您将修改实现文件,并且不需要完全重新编译.

您的变体中的问题不是与编译相关的,而是与逻辑相关的.它们不是全局变量,因为每个翻译单元都有自己的变量副本.

编辑:

C++ - 这样做的方法实际上将它们包装在一个类中:

//constants.h
class Constants
{
public:
   static const bool doX;
   static const bool doY;
   static const int maxNumX;
}

//constants.cpp
const bool Constants::doX = true;
const bool Constants::doY = false;
const int Constants::maxNumX = 5;
Run Code Online (Sandbox Code Playgroud)

  • 我会说他们C++的方式是将它们包装在命名空间而不是类中. (11认同)
  • 我会说这是Java-ish方法. (9认同)

Alo*_*ave 4

这种用法有什么问题吗?
不要static在头文件中声明类型,它不会执行您认为它会执行的操作。

当您在头文件中声明静态变量时,会在包含该头文件的每个翻译单元(TU)中创建该变量的副本,因此每个 TU 都会看到不同的变量,这与您对全局变量的期望相反。

建议的解决方案:
您应该在头文件中声明它们extern,并在一个 cpp 文件中定义它们,同时在extern要访问它们的每个 cpp 文件中包含标头。

好读:
我应该如何使用 extern?

  • 在这种情况下(因为它们是 const),我实际上会使用 static (我的意思是我不会声明它们任何东西,只是不使它们成为外部(因此默认为静态))。因为它为编译器提供了更好的机会来完全优化掉该值。 (2认同)