本周小贴士#103:Flag是全局变量

Posted -飞鹤-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了本周小贴士#103:Flag是全局变量相关的知识,希望对你有一定的参考价值。

由Matt Armstrong创作

在.cc文件中的全局作用域中定义flag。至多在相应.h文件中声明它们一次。

为什么在头文件中声明?

对于我们大多数人而言,使用头文件是本能反应,因此我们可能忘记为什么使用它们:

  1. 在头文件声明的内容很容易在其他地方#include。整个程序会看到相同的声明。
  2. 在定义了相同实体的.cc文件中引入此头文件可确保定义与声明匹配。
  3. 头文件用作包的公共API的文档。使用包的公共API之处的任何内容都是糟糕的形式。
  4. 引入头文件,而不是重复声明实体,有助于工具和人执行依赖性分析。

Abseil Flag像其他全局变量一样脆弱

你可以错误地执行此操作而没有链接时错误。首先,将下列内容放入.cc文件中:

// 定义 --在.cc文件中的my_flag
ABSL_FLAG(std::string, my_flag, "", "My flag is a string.");

接着,这下面的在不同.cc文件中错误的flag声明(可能是一个测试):

// 错误声明: 类型应该是std::string.
extern absl::Flag<int64> FLAGS_my_flag;

程序型式上错误,无论发生什么结果都是未定义行为。在我的测试程序中,这份代码能够编译,链接,接着在flag被访问时会崩溃。

推荐

像你使用全局变量一样来设计命令行flag。

  1. 尽可能避免flag。参见http://abseil.io/tips/45.
  2. 如果你使用flag是为了更容易编译测试,而无意于在生产中使用它,那么考虑向你的类中添加仅用于测试的API.
  3. 考虑将flag作为私有静态变量。如果其他包想访问它们,在函数中封装它们。
  4. 在全局作用域中定义你的flag,不要在命名空间中,这样当flag名字冲突时会链接错误。
  5. 如果一个flag在多个文件中被访问,那么在一个与它定义相应的.h文件中声明它。
  6. 使用ABSL_FALG(type,…)宏定义flag.

结论

flag是全局变量。审慎地使用它们。像你用其他全局变量一样使用和声明它们。

以上是关于本周小贴士#103:Flag是全局变量的主要内容,如果未能解决你的问题,请参考以下文章

本周小贴士#101:返回值,引用和生命周期

本周小贴士#74:委托和继承构造函数

本周小贴士#123: absl::optional和std::unique_ptr

本周小贴士#147:负责地使用穷举witch语句

本周小贴士#147:负责地使用穷举witch语句

本周小贴士#55:名字计数与unique_ptr