可能重复: 全局变量不好吗?
我正在编写一个模拟代码,利用具体的材料和能源数据。这些数据存储在全局数组中,因为一旦上传,这些数据将在模拟过程中使用,大多数函数都应该可以访问这些数据。
我到处读到,使用全局变量并不是一个好的实践。有人能解释我,或者指点我网上的材料,解释我如何避免在模拟应用程序编码中使用全局数组,而需要使用大量的数据数组。我尝试用C++编写代码,并尽可能多地使用面向对象的特性。
提前谢谢你的帮助。
发布于 2011-07-23 10:53:52
你说得对,不推荐使用全局值。你可以在namespace中声明那些不相关的高尔夫球,
//Globals.h
namespace Globals
{
extern int a[100];
extern double d;
}并在.cpp文件中定义它们。
//Globals.cpp
int Globals::a[100] = { ... };
double Globals::d = 3.14;现在将它们用作Globals::a、Globals::d等。我的回答是从代码管理的角度出发。
发布于 2011-07-23 10:54:47
看看本文是关于全局变量的。这是一段节选:
为什么在没有必要的时候应该避免全局变量 当单个元素的范围受到限制时,非局部性源代码最容易理解。程序的任何部分都可以读取或修改全局变量,因此很难记住或解释每一个可能的用途。 没有访问控制或约束检查--程序的任何部分都可以获得或设置全局变量,任何有关其使用的规则都很容易被打破或忘记。(换句话说,get/set访问器通常比直接数据访问更可取,对于全局数据更是如此。)因此,在您可能希望运行不受信任的代码(例如使用第三方插件)的情况下,缺乏访问控制极大地阻碍了安全性的实现。 隐式耦合--一个包含许多全局变量的程序,其中一些变量之间经常有紧耦合,变量和函数之间有耦合。将耦合的项目组合成内聚单元通常会导致更好的程序。 并发问题--如果全局可以被多个执行线程访问,同步是必要的(而且常常被忽略)。当动态地将模块与全局连接时,即使在几十个不同的上下文中测试的两个独立模块是安全的,组合系统也可能不是线程安全的。 名称空间污染--全球名称随处可见。当您认为您使用的是本地(拼写错误或忘记声明本地)时,您可能在不知不觉中使用全局语言,反之亦然。此外,如果您必须将具有相同全局变量名称的模块链接在一起,如果您幸运,您将得到链接错误。如果您运气不好,链接器将简单地将所有相同名称的用法视为相同的对象。 内存分配问题--有些环境有内存分配方案,使得全局分配变得棘手。在“构造函数”除了分配有副作用的语言中尤其如此(因为在这种情况下,您可以表示两个全局相互依赖的不安全情况)。此外,在动态链接模块时,可能不清楚不同的库是否有它们自己的全局实例,或者是否共享全局。 测试和限制-使用全局的源更难测试,因为一个人无法在运行之间建立一个“干净”的环境。更普遍地说,由于同样的原因,使用任何类型的全局服务(例如读写文件或数据库)而没有明确提供给该源的源很难进行测试。对于通信系统,测试系统不变量的能力可能需要同时运行一个系统的多个“副本”,这在很大程度上受到共享服务(包括全局内存)的任何使用的阻碍,这些服务不是作为测试的一部分提供给共享的。
它还讨论了几种备选方案。在你的情况下,你可以考虑:
编辑:
我理解开发社区的一部分反对使用单例模式。我完全尊重这一意见。无论如何,在当前讨论的背景下,单例比原始地使用globals具有几个优点:
在这方面,使用setter/getter函数集并不更好,但更糟的是。我把选择如何处理自己的代码的艰巨任务留给OP。(顺便说一句,本文讨论了更多的方法,如上下文对象、DependencyInjection等)。
发布于 2011-07-23 10:55:04
在代码中引入全局状态可能会使以多线程方式执行任务变得困难。
我也认为这会使代码的意图更难理解。如果将所有参数作为参数传递给函数,那么函数可以访问哪些数据,以及哪些数据具有更改的潜力,这一点至少是显而易见的。全局变量的使用不会给阅读代码的人这个机会..。
使用全局变量以任何方式都快的说法也是不正确的。如果您有需要传递给函数的大型对象,则通过引用传递这些参数,并且复制不会出现任何问题。
在不了解更多关于您的设置的情况下,很难提出任何建议,但是如果您有大量需要传递给一系列例程的数据,我会倾向于将其全部放在struct中,并通过引用传递该struct:
struct my_data_type
{
double some_data;
double some_other_data;
std::vector<double> some_coefficients;
std::vector<double> some_other_coefficients;
std::string some_name;
std::string some_other_name;
// add more members as necessary...
};
void foo(my_data_type &data)
{
// there's no big overhead passing data by reference
}如果您只需要以只读方式访问数据,最好以const引用的形式传递:
void foo(my_data_type const&data)
{
// again, efficient, but ensures that data can't be modified
}编辑:在回答你的评论时,我说的不是“全球”结构。您需要声明一个本地struct变量,将文件中的数据读取到struct中,然后通过引用传递给需要调用的任何函数:
int main()
{
// a local struct to encapsulate the file data
my_data_type file_data;
// read the data from your file into file_data
// the struct containing the data is passed by reference
foo(file_data);
return 0;
}https://stackoverflow.com/questions/6799892
复制相似问题