如何避免涉及全局变量的循环 #include?
How to avoid a circular #include involving a global variable?
我有一个声明两个全局对象的标头myglobal.h
:
#include "log.h" // defines Clog
Clog log_file;
#include "lib.h"
Clib main_lib;
但是,我的lib.h
也使用全局标头:
#include "myglobal.h" // error: circular #include
class Clib
{
void func(void) { log_file << "hello"; }
}
如何编写这些标头以避免#include
循环?
在头文件中添加extern
,
// myglobal.h
#include "log.h"
extern Clog log_file;
// #include "lib.h" DO NOT include this one
extern Clib main_lib;
然后在 cpp 文件 (log.cpp) 中定义它
#include "log.h"
Clog log_file;
并将 clib 的定义也move
到 cpp 文件(例如 lib.cpp)。
#include "myglobal.h"
void Clib::func(void) { log_file << "hello"; }
如果无法将定义移出头文件,则只需要一个 cpp 文件来定义Clib main_lib
。除此之外,只要您包含对所有标头的防护,它应该没问题。
循环 #include 的根本问题是循环思维。特别是,全局标头的概念既定义又依赖于您的库。
您可以通过不依赖于库实现中的myglobal.h
来解决此问题。一种简单的方法是将CLib::func
移动到lib.cpp
首先,如 CS Pei 的回答中所述,请注意您需要包含守卫,并且头文件中的变量声明需要extern
(以及源文件中的单独定义)。 在 C++17 中,您可以改用inline
,并让链接器对其进行排序。
同时,根据您的用例,有一些策略可供选择。
前向声明Clib
myglobal.h
只声明Clib
,而不是定义它:
#include "log.h"
extern Clog log_file;
class Clib;
extern Clib main_lib;
然后可以毫无问题地#include
lib.h
。 但是,单独#include"myglobal.h"
的客户端将无法使用main_lib
,因为它的类型不完整。
将log_file
放在其自己的标头中
由于Clib
不仅依赖于Clog
,还依赖于log_file
,因此它显然处于更高的接口级别。 通过创建globallog.h
将其形式化:
#include "log.h"
extern Clog log_file;
然后lib.h
可以包括没有循环性的内容:
#include "globallog.h"
class Clib
{
void func(void) { log_file << "hello"; }
}
最后,myglobal.h
包括这一点并添加main_lib
:
#include "globallog.h" // optional: clarifies that log_file is made available
#include "lib.h"
extern Clib main_lib;
声明全局对象及其类
在lib.h
中声明main_lib
如果没有文件想要没有(您当前的)myglobal.h
lib.h
(可能是因为唯一使用的Clib
是main_lib
),您可以将main_lib
声明移动到lib.h
:
#include "myglobal.h" // only log_file now
class Clib
{
void func(void) { log_file << "hello"; }
}
extern Clib main_lib;
请注意,这是之前"log_file
在其自己的标头中"策略的变体,其中log_file
是现有标头中唯一保留的内容。
在log.h
中声明log_file
对称地,如果没有文件想要log.h
而不使用log_file
,请在此处声明它并只留下myglobal.h
main_lib
:
#include "lib.h"
extern Clib main_lib;
那么lib.h
只是
#include "log.h"
class Clib
{
void func(void) { log_file << "hello"; }
}
- 如何循环打印顶点结构
- 如何在C++中从两个单独的for循环中添加两个数组
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 正在尝试了解输入验证循环
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 循环后如何继续阅读
- Ardunio UNO解决了多个重叠的定时器循环
- Eigen如何在容器循环中干净地附加矩阵
- 在某些循环内使用vector.push_back时出现分段错误
- 既然存在危险,为什么项目要使用-I include开关
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- 有充分的理由在h文件中使用include保护而不是cpp文件吗
- 如何处理模板类标头中的循环 #include 调用
- 实现递归函数,避免由 C++ 中 include 的循环调用(没有 #pragma 一次)引起的无限循环输入
- 如何避免涉及全局变量的循环 #include?
- C++:由于 #include 循环,无法将对象实例传递给另一个类
- #include 循环依赖项错误
- 如何解决此循环include
- friend函数和include循环
- 无尽的include循环