我有一个标题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
循环?
答案 0 :(得分:1)
在标题文件中添加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;
和move
clib的定义也是一个cpp文件(例如lib.cpp)。
#include "myglobal.h"
void Clib::func(void) { log_file << "hello"; }
如果无法将定义移出头文件,则只需要一个cpp文件来定义Clib main_lib
。除此之外,只要你有所有标题包含警卫就应该没问题。
答案 1 :(得分:0)
你的通告#include的根本问题是循环思考。特别是,全局标题的概念既定义又取决于您的库。
您可以通过而不是解决此问题,具体取决于您的库实现中的myglobal.h
。一种简单的方法是将CLib::func
移至lib.cpp
答案 2 :(得分:0)
首先,正如CS Pei的回答所述,请注意您需要包含警卫,并且头文件中的变量声明需要extern
(以及源文件中的单独定义)。在C ++ 17中,您可以use inline
instead并让链接器对其进行排序。
同时,根据您的使用情况,有一些策略可供选择。
Clib
让myglobal.h
仅声明Clib
,而不是定义它:
#include "log.h"
extern Clog log_file;
class Clib;
extern Clib main_lib;
然后#include
d lib.h
d #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;
并添加main_lib
:
lib.h
lib.h
myglobal.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;
的声明即可1}}进入log_file
:
log_file
请注意,这是之前“log_file
在其自己的标头”策略中的变体,其中log.h
是现有标头中唯一的 left 。
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"; }
}
然后public class AlertVm
{
public int EmailCount { set; get; }
public int NotificationCount { set; get; }
}
只是
[ChildActionOnly]
public ActionResult Alerts()
{
var vm = new AlertVm {EmailCount = 4, NotificationCount = 2};
return PartialView(vm);
}