我正在编写一个使用材料和能源特定数据的模拟代码。这些数据存储在全局数组中,因为一旦上传,它们就会在模拟过程中使用,大多数函数都可以访问它们。
我到处读到使用全局变量不是好习惯。 有人可以向我解释或指向网上的材料,解释如何避免在模拟应用编码中使用全局数组,同时需要使用海量数据阵列。我尝试用C ++编写代码并尽可能多地使用面向对象的功能。
提前感谢您的帮助。
答案 0 :(得分:1)
是的,你是对的,全局变量并不好。 这是一个有用的链接,它解释了为什么全局变量是坏的以及如何避免它们。
http://c2.com/cgi/wiki?GlobalVariablesAreBad
编辑: @sergio的帖子也指向同一个链接,你可以忽略这个答案
答案 1 :(得分:1)
有人可以向我解释一下,或者向我指出如何在网络上解释如何避免在模拟应用程序编码中使用全局数组,同时需要使用海量数据阵列。
一般来说,避免使用全局变量的方式相同:改为使用局部变量。将数据导入函数的自然方法是将其作为参数传递。这并不昂贵,特别是如果您在适当的地方通过引用。
答案 2 :(得分:0)
你是对的,不建议使用全局变量。你可以在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
等。我的答案是在代码管理方面。
答案 3 :(得分:0)
看看this article about global variables。这是一段摘录:
为什么在不必要时应避免使用全局变量
非本地化 - 当各个元素的范围有限时,源代码最容易理解。全局变量可以被程序的任何部分读取或修改,使得难以记住或推理每种可能的用途。
无访问控制或约束检查 - 程序的任何部分都可以获取或设置全局变量,并且可以轻松地删除或忘记有关其使用的任何规则。 (换句话说,获取/设置访问器通常比直接数据访问更受欢迎,对于全局数据更是如此。)通过扩展,缺少访问控制极大地阻碍了在您可能希望运行不受信任的代码的情况下实现安全性(例如使用第三方插件)。
隐式耦合 - 具有许多全局变量的程序通常在这些变量之间存在紧密耦合,以及变量和函数之间的耦合。将耦合项目分组为有凝聚力的单元通常会带来更好的计划。
并发问题 - 如果多个执行线程可以访问全局变量,则需要进行同步(并且经常被忽略)。当动态链接模块与全局变量时,即使在几十个不同的上下文中测试的两个独立模块是安全的,组合系统也可能不是线程安全的。
命名空间污染 - 全球名称随处可见。当您认为使用本地(通过拼写错误或忘记声明本地)时,您可能会在不知不觉中最终使用全局,反之亦然。此外,如果您必须将具有相同全局变量名称的模块链接在一起,如果幸运的话,您将收到链接错误。如果您运气不好,链接器将只处理与同一对象同名的所有用途。
内存分配问题 - 某些环境具有内存分配方案,使得全局变量分配变得棘手。在“构造函数”具有除分配之外的副作用的语言中尤其如此(因为,在这种情况下,您可以表示两个全局变量彼此相互依赖的不安全情况)。此外,在动态链接模块时,可能不清楚不同的库是否有自己的全局变量实例或者是否共享全局变量。
测试和限制 - 使用全局变量的源更难以测试,因为在运行之间无法轻易建立“干净”的环境。更一般地,利用未明确提供给该源的任何类型的全局服务(例如,读取和写入文件或数据库)的源很难以相同的原因进行测试。对于通信系统,测试系统不变量的能力可能需要同时运行系统的多个“副本”,这在任何使用共享服务(包括全局内存)时都会受到很大阻碍,这些共享服务不作为测试的一部分提供共享
它还讨论了几种替代方案。可能在你的情况下,你可以考虑:
隐藏你的全局变量(例如私有静态变量);
有状态程序:setter和getter函数允许访问数组,同时“屏蔽”它;
编辑:
我知道开发社区的一部分反对使用单例模式。我完全尊重这个意见。无论如何,在本讨论的背景下,单例提供了几个优于全局使用的优点:
改进了访问控制;
同步的机会;
抽象实施的能力。
在这方面,从setter / getter函数集来看并不是更好,但仍然不会更糟。我向OP留下了选择如何处理自己的代码的艰巨任务。 (顺便说一句,本文讨论了更多方法,如Context Objects,DependencyInjection等)。
答案 4 :(得分:0)
在代码中引入全局状态会使以多线程方式执行操作变得困难。
我还认为它可能会使代码的意图更难以遵循。如果将所有参数作为参数传递给函数,至少可以清楚函数可以访问哪些数据,以及哪些数据有可能发生变化。全局变量的使用并没有让人有机会阅读代码......
使用全局变量的速度通常也不是很快。如果您需要传递给函数的大对象,请通过引用传递这些参数,并且复制不会有任何问题。
在不了解您的设置的情况下,很难提出任何建议,但如果您需要将大量数据传递给一系列例程,我很想把它全部放在{{1并通过引用传递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