我知道全局变量很糟糕,应该尽可能避免。但是,例如,在使用MPI编写并行程序时,某些变量只会初始化一次,并且永远不会更改(此任务的编号,任务总数等)。将这些变量视为全局变量仍被视为不良做法吗?由于您几乎总是需要访问这些变量,因此在main中为它们创建一个类似乎很愚蠢,并将指针传递给程序中99%的所有函数。到目前为止,我的方法是将它们隐藏在命名空间mpi_glob中(对于C ++的情况,我想我不会费心将它们放在C中的结构中来模拟命名空间)。我想这个问题也适用于其他只设置一次的变量,例如单位系统等。
答案 0 :(得分:5)
全局变量“不好”的原因是它们引入了难以识别和跟踪的单独源文件之间的耦合。特别是,如果全局变量在程序中的某个点处具有意外状态,则很难确定它在何处被修改。
使用通过引用程序中的每个函数传递的局部变量替换全局变量并不能消除该问题。在设计方面,它是“流浪汉数据”,即即使不需要也会徘徊的数据。
现在,重点在于,正如您所建议的那样,初始化一次但从未改变的数据没有使全局变量“变坏”的问题。由于问题不存在,因此不需要解决方案。
答案 1 :(得分:0)
悬崖上不应该遵循任何规则,具体细节完全取决于你所编写的程序类型。
如果您的程序相对较小(或者您是唯一一个编写/维护它的程序),那么将“全局”变量留在特殊名称空间中可能就好了。至少在某种程度上你不可能在局部范围内意外地遮挡或踩踏它们。那假设你没有做过这样的事情:
using namespace mpi_glob;
这与将文件中的全局变量放在某个地方有点不同,但并不能保护它们。
如果使用全局变量使程序更清晰易懂,则使用它们。如果可以将它们保持在本地,请将它们保持在本地,因为从长远来看,它通常会使维护更简单。
答案 2 :(得分:0)
我认为Singleton应该可以帮助你更好地管理它,所以你不必传递指针。实际上,mpi_glob
也是如此,Singleton
只是更习惯的方式。
或者,你仍然可以使用全局变量 - 它们也不是坏事。如果您想强调一次性作业,可以声明它们const
并通过静态初始化程序设置它们,如下所示:
const int number_of_tasks = get_preconfigured_number_of_tasks();
如果您的全局变量用于保存编译时常量,那么用enum
成员或预处理器定义替换它们就完全没问题了。这样做可以简化编译器,因为它可以在没有内存访问的情况下就地使用立即值。
Pete Becker在评论中指出了Singleton问题。如果这些问题也困扰你,那么可以采取完全不同的方法。
还记得Java程序是如何实现的吗?主要方法有主类,所有程序的工作从主要方法内部运行。 Main仍然是成员函数,即它可以独占访问主类的一些私有字段(在Java的情况下它们必须是静态的,但这不是主要的点)。
我们可以将概念进一步扩展到Command - 就像实现一样。与传统Java的区别在于,您的main方法等价物不是静态的,并且具有特定于包含程序的值的全局变量是非静态成员变量。需要访问全局状态数据的所有函数都将转换为成员函数。这是可能的,因为main方法也是成员函数。
这样,我认为,您可以实现更好的封装和数据安全。