在C ++中适当使用全局const变量?

时间:2011-09-19 06:34:36

标签: c++ global-variables const

我正在为我的CS课程开发一个程序。它模拟了送货公司在机场的活动。

这是一个非常简单的小程序,包含一些头文件和源文件以及一个编排模拟的main.cpp源文件。

存在某些给定的常数值,例如装运到达的频率,飞机的负载能力,工人处理某些物品所花费的时间等等(均为整数值)。我需要在main.cpp

中的几个函数中访问这些变量

将main()函数上面的这些声明为const整数似乎是合理的,有效地使它们成为全局的,例如

const int kTotalTime = 2000;
const int kPlaneCapacity = 25;
int main(){//...program code}

我知道在大多数情况下都要避免使用全局变量,因为对它们的调用和/或修改位置没有限制,这可能导致意外破坏程序的某些部分,这反过来可能很难调试,以及导致未来代码的兼容性问题等。 但是,由于这些是整个程序中使用的原始数据类型的只读值,因此它似乎是一种合理的解决方案。此外,它还向读取代码的任何人以及编译器明确说明了变量的用途。

问题:我的逻辑有缺陷吗?怎么会这样?全局变量(常量或非常量)何时合理使用?如果这是一个不好的解决方案,那么你会如何建议声明这些常量只读值?

非常感谢你的时间!

3 个答案:

答案 0 :(得分:5)

我认为最好将常量作为静态放在类中。

我假设您有班级Plane,只需这样做:

Plane.h

class Plane{
   static const int kPlaneCapacity;
   //....
}

Plane.cpp

const int Plane::kPlaneCapacity = 25;

另外,要注意不断理解你的理解。 Pi是一个常数。 10是常数。我确实看到你如何认为飞机的容量是恒定的,但想一想:如果你的老师说你的下一个任务,你的飞机容量应该是30,而不是25。

答案 1 :(得分:5)

关于你的程序的大小和目的(正如我从你的描述中理解的那样)它可能无关紧要,但由于它具有教育背景,我建议“做得对

在这种情况下,我会选择一个Config结构(或类,如果你想让它更聪明,见下文),它带有配置值,可以在程序周围抛出。它的优点是,如果您必须从文件或命令行中获取选项,则可以轻松更改它。

至于类与结构的东西(请注意,我在这里做出了逻辑上的区别,而不是技术上的区别)。您可以将所有值作为成员放在结构中并传递给它的const引用,或者使它成为一个完整的类,其中包含隐藏数据来源(及其生成方式)的访问器。编程始终是决策,这是您的决定。如果您认为将来必须允许更多配置(如上所述),您可能想要进行类抽象。

另一种选择是将数据分散到整个程序中,这实际上比听起来要聪明得多。如果每个类只知道它的配置选项(并隐藏它们),你实际上可以使用你正在使用的OOP语言。例如:

// footype.h
class FooType {
  private:
    static const int fooOption;
};
// bartype.h
class BarType {
  private:
    static const float barOption;
};

问题是,如何初始化这个。一种方法是创建一个如下所示的config.cpp

#include "footype.h"
#include "bartype.h"

const int FooType::fooOption = 42;
const float BarType::barOption = 7.4;

因此您隐藏了信息,并且您仍然可以在一个地方(config.cpp)将所有配置选项放在一起。

编辑:

如果您有许多(多个)不同模块所需的配置选项,您可以进行一些复杂化(使用间接),如下所示:

// footype.h
class FooType {
  private:
    static const int& fooOption;
    static const bool& dumpLevel;
};
// bartype.h
class BarType {
  private:
    static const float& barOption;
    static const bool& dumpLevel;
};

config.cpp:

#include "footype.h"
#include "bartype.h"

static const int opt_foo = 42;
static const float opt_bar = 7.4;
static const bool opt_dumpLevel = false;

const int& FooType::fooOption = opt_foo;
const bool& FooType::dumpLevel = opt_dumpLevel;
const float& BarType::barOption = opt_bar;
const bool& BarType::dumpLevel = opt_dumpLevel;

如果需要,您甚至可以选择非const(但我没有看到配置选项中的点是可变的)。

答案 2 :(得分:3)

全局变量(常量或非常量)何时合理使用?

如果您的程序是多线程程序,那么您应该认真考虑使用全局变量,因为它们需要正确的同步以避免竞争条件。通常,正确的同步不是一项非常简单的任务,需要一些严肃的不受欢迎和思考。

以下摘自 nice article

  

非本地化 - 当各个元素的范围有限时,源代码最容易理解。全局变量可以由程序的任何部分读取或修改,使得难以记住或推理每种可能的用途。   无访问控制或约束检查 - 程序的任何部分都可以获取或设置全局变量,并且可以轻松地删除或忘记有关其使用的任何规则。

     

隐式耦合 - 具有许多全局变量的程序通常在这些变量之间存在紧密耦合,以及变量和函数之间的耦合。将耦合项目分组为有凝聚力的单元通常会带来更好的计划。

     

内存分配问题 - 某些环境具有内存分配方案,使得全局分配变得棘手。在“构造函数”具有除分配之外的副作用的语言中尤其如此(因为,在这种情况下,您可以表示两个全局变量彼此相互依赖的不安全情况)。此外,当动态链接模块时,可能不清楚不同的库是否有自己的全局变量实例或者是否共享全局变量。

     

测试和限制 - 使用全局变量的源更难以测试,因为在运行之间无法轻松建立“干净”的环境。更一般地,利用未明确提供给该源的任何类型的全局服务的源很难以相同的原因进行测试。

考虑到以上所述,只要你理解了陷阱并理解你使用全局变量的方式确实使你的程序与这些陷阱绝缘,那么你可以继续并且很好地使用全局变量。