在头文件中使用“extern const”使全局变量只读

64jmpszr  于 5个月前  发布在  其他
关注(0)|答案(4)|浏览(41)

我在尝试GCC,发现你可以在头文件中声明变量const,但在实现文件中保持可变。

header.h:

#ifndef HEADER_H_
#define HEADER_H_

extern const int global_variable;

#endif

字符串
header.c:

int global_variable = 17;


这使得global_variable对于实现是可修改的,但是const对于包含header.h的每个文件都是可修改的。

#include "header.h"

int main(void)
{
    global_variable = 34; /* "header.h" prevents this type of assignment. */
    return 0;
}


这种技术是否在实践中使用?
在C中构建接口时,人们经常建议使用get-函数来检索全局状态。这种方法有什么优点吗?
对我来说,这种方法似乎更清晰,并且每次有人试图访问global_variable时都不会增加函数调用的开销。

ufj5ltwl

ufj5ltwl1#

这两种方法在实践中都有使用,但大多数情况下的最佳实践是避免全局变量和静态。
注意:你的问题标记为C和C++,这是C++的方法。
更好的方法是创建一个包含“全局”状态的类,并将其传递给需要全局变量和常量的函数,这称为“上下文”。
上下文对象可以使用适当的信息隐藏来控制谁可以更新它的状态,验证它的状态等,就像任何其他对象一样。另外,它完全避免了对全局变量的需要,这是一个反模式。

tyky79it

tyky79it2#

实际无效。

举个例子。
header.h:

#ifndef HEADER_H_
#define HEADER_H_

extern const int global_variable;

#endif

字符串
header.c:

#include "header.h"

int global_variable; // Here will the compiler complain!


这将无法编译,因为intconst int是不兼容的类型。我让自己的测试工作的唯一原因是因为我没有包括“header.h”在“header.c”中。

9vw9lbht

9vw9lbht3#

get函数允许以后插入新的逻辑(例如验证)。如果你从一个全局变量开始,后来发现你需要新的逻辑,添加一个get函数是一个突破性的变化。

jdg4fx2g

jdg4fx2g4#

这是一种C++11之前的方法,可能有一些缺陷:实际上它依赖于链接器来维持解析。如果所有值都很简单,这不是一个大问题,但是如果一个值不是POD并且依赖于其他值,因为链接顺序不是由源指定的,这可能会暴露于“全局初始化失败”。
在头文件中,它有时可能有一个更直接的方法,

static constexpr int global_constant = xx;

字符串
static关键字使得global_constant对于每个独立的翻译单元是本地的,从而避免了仅定义一次“通用全局对象”的需要。
这种方法也与“Header only libraries”兼容,这是泛型代码必须的。

相关问题