我正在尝试使用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;
}
这种技术是否在实践中使用?
人们经常建议使用get
- 函数来在C语言中构建接口时检索全局状态。对此方法有什么优势吗?
对我来说,这种方法似乎更加清晰,并且每次有人试图访问global_variable
时都没有额外的函数调用开销。
答案 0 :(得分:3)
这两种方法都在实践中使用,但大多数情况下的最佳做法是避免全局变量和静态。
注意:您的问题标记为C和C ++,这是C ++方法。
更好的方法是创建一个包含" global"状态并将其传递给否则需要全局变量和常量的函数。这被称为"上下文。"
上下文对象可以使用适当的信息隐藏来控制谁可以更新其状态,验证其状态等,就像任何其他对象一样。此外,它完全避免了对全局变量的需求,这是一种反模式。
答案 1 :(得分:2)
get
函数允许稍后插入新逻辑(例如验证)。如果你从一个全局变量开始并稍后发现你需要新逻辑,那么添加一个get
函数就是一个重大改变。
答案 2 :(得分:2)
举个例子。
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!
由于int
和const int
不兼容,因此无法编译。我自己的测试工作的唯一原因是因为我在“header.c”中 NOT 包含“header.h”。
答案 3 :(得分:0)
这是一种前C ++ 11的做法,可能会有一些陷阱:实际上它依赖于链接器来维持分辨率。如果所有值都很简单,那么这不是一个大问题,但是如果某个值不是POD并且依赖于其他值,因为源不指定链接顺序,这可能会暴露给“全局初始化惨败”。
内部头文件有时可能采用更简单的方法
static constexpr int global_constant = xx;
static关键字使每个独立翻译单元的global_constant
本地化,避免只需定义一次“通用全局对象”。
这种方法也与“仅头文件库”兼容,这是通用代码必须的。