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

问题描述 投票:0回答:4

我正在尝试使用 GCC,发现您可以在头文件中声明变量

const
,但在实现文件中保持它们可变。

编辑:这实际上不起作用,请检查我自己的答案。

标题.h:

#ifndef HEADER_H_
#define HEADER_H_

extern const int global_variable;

#endif

标题.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

c header-files api-design
4个回答
4
投票

这两种方法都在实践中使用,但大多数情况下的最佳实践是避免全局变量和静态状态。

注意:你的问题被标记为C和C++,这是C++方法。

更好的方法是创建一个包含“全局”状态的类,并将其传递给需要全局变量和常量的函数。这称为“上下文”。

上下文对象可以使用适当的信息隐藏来控制谁可以更新其状态、验证其状态等,就像任何其他对象一样。另外,它完全避免了对全局变量的需要,这是一种反模式。


3
投票

这实际上是无效的。

举这个例子。

标题.h:

#ifndef HEADER_H_
#define HEADER_H_

extern const int global_variable;

#endif

标题.c:

#include "header.h"

int global_variable; // Here will the compiler complain!

这不会编译,因为

int
const int
不是兼容的类型。我自己的测试工作的唯一原因是因为我NOT在“header.c”中包含“header.h”。


2
投票

get
函数允许稍后插入新逻辑(例如验证)。如果您从全局变量开始,后来发现您需要新的逻辑,那么添加
get
函数就是一个重大更改。


0
投票

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

在头文件内部有时可能有更直接的方法a

static constexpr int global_constant = xx;

static 关键字使

global_constant
本地化到每个独立的翻译单元,避免了只定义一次“通用全局对象”的需要。

此方法还与“仅标头库”兼容,这是通用代码必须的。

© www.soinside.com 2019 - 2024. All rights reserved.