什么时候应该使用静态数据成员与const全局变量?

Edu*_*rdo 5 declaration global-variables static-members linkage c++11

声明const全局变量已证明对确定API的某些功能参数很有用.例如,在我的API上,运算符的最小数值精度顺序为2; 因此,我宣布:

const int kDefaultOrderAccuracy{2};
Run Code Online (Sandbox Code Playgroud)

作为全球变量.将它作为static const描述这些运算符的类的公共数据成员会更好吗?一般来说,选择一个比另一个更好?

cur*_*guy 1

const int kDefaultOrderAccuracy{2};
Run Code Online (Sandbox Code Playgroud)

是静态变量的声明:kDefaultOrderAccuracy具有内部链接。将具有内部链接的名称放在标头中显然是一个极其糟糕的主意,这使得在同一或其他标头中具有外部链接的其他代码中很容易违反单一定义规则(ODR),特别是当名称在正文中使用时内联函数或模板函数的:

f.hpp 内部:

template <typename T>
const T& max(const T &x, const T &y) {
  return x>y ? x : y;
}

inline int f(int x) {
  return max(kDefaultOrderAccuracy, x); // which kDefaultOrderAccuracy?
}
Run Code Online (Sandbox Code Playgroud)

一旦包含f.hpp两个 TU(翻译单元),就会违反 ODR,因为定义不是唯一的,因为它使用命名空间静态变量:kDefaultOrderAccuracy定义指定的对象取决于编译它的 TU。

类的静态成员具有外部链接:

struct constants {
  static const int kDefaultOrderAccuracy{2};
};

inline int f(int x) {
  return max(constants::kDefaultOrderAccuracy, x); // OK
}
Run Code Online (Sandbox Code Playgroud)

constants::kDefaultOrderAccuracy程序里只有一个。

您还可以使用命名空间级别的全局常量对象:

extern const int kDefaultOrderAccuracy;
Run Code Online (Sandbox Code Playgroud)