我正在做一个小的软件项目,我希望在将来以开源的形式发布,所以我希望收集关于这个问题的最佳实践的意见。
应用程序本身是过程的,不是面向对象的(我不需要在类中封装呈现函数或事件处理函数),但是应用程序的某些方面是严重面向对象的(如脚本控制台,严重依赖于OO)。代码的OO方面有标准的object.cpp
和object.h
文件。
对于过程部分,我将代码拆分为各种文件(例如main.cpp
, render.cpp
, events.cpp
),每个文件都可能具有特定于该文件的一些全局变量。我也有相应的头文件为每个,定义所有的函数和变量(如extern
),我想从其他文件访问。然后,当我需要从另一个源文件访问该函数/变量时,我只需#include
正确的头文件。
我今天意识到,我也可以有另一个选择:创建一个单独的globals.h
头文件,在那里我可以定义所有的全局变量(再次作为extern
)和函数,将需要一个特定的源文件之外。然后,我可以在所有源文件中#include
这个文件(而不是像现在这样每个单独的头文件)。此外,使用此方法,如果我需要将变量/函数提升为全局(而不是局部),我可以将该条目添加到头文件中。
问题:这是一个更好的做法,使用相应的头文件为每一个单独的.cpp
文件(并定义变量/函数,我想在这些头全局访问),或使用单个头文件来声明所有全局可访问的变量/函数?
另一个快速更新,大多数(但不是所有)的全局变量是这样使用的,因为我的应用程序是多线程的。
对我来说,最好有一个对应于每个实现(c或cpp)文件的头文件。你必须把你的类、结构和函数看作模块,如果你分割你的实现,那么你分割你的声明也是合乎逻辑的。
另一件事是,当您修改头文件时,它会导致所有包含它的文件在构建时被重新编译。最后我可以告诉你,这需要很长时间。您可以通过适当地拆分声明来避免重新构建所有内容。
我建议增加标题,减少标题。你必须有一连串的包含,但这很容易理解和编辑,如果它是错误的。
如果事情变得古怪,有一个大的全局变量更难应付。如果你必须改变某些东西,那么这种改变可能影响深远,而且风险很高。
在这种情况下,更多的代码并不是一件坏事。
一个小问题是,你的编译时间将增加超线性,你把更多的一个大的头文件,因为每个文件都必须处理它。在嵌入式项目中,这可能不太值得担心,但一般来说,在标题中有很多内容将开始使您负担过重。
最好将它们全部放在一个文件中,根本不编译该文件。如果您有全局变量,您应该重新考虑您的设计,特别是如果您正在进行应用程序编程而不是低级系统编程。
正如我在问题下面的评论中所说,要做的第一件事是尝试消除所有全局数据。如果这是不可能的,而不是一个大的头,或抛出外部到每个类的头,我将遵循第三种方法。
假设您的Event
类需要有一个全局实例。如果您在event.cpp
中声明全局实例并在event.hpp
中对其进行extern,那么这实际上使这些文件在其他任何地方都无法重用。将其放入globals.cpp
和globals.hpp
也不理想,因为每次修改全局头文件时,您的整个项目都将重新构建,因为每个人都包含头文件。
因此,第三种选择是为每个需要具有全局实例的类创建附带的头文件和源文件。因此,您可以在event_g.cpp
中声明Event
全局实例,并在event_g.hpp
中extern它。
是的,它很丑,是的,它很乏味。但是全局数据没有什么好看的