c ++全局变量的后期实例化

时间:2012-12-01 23:44:27

标签: c++ c++11

我有代码,其中必须通过相当多的代码来设置全局资源:

globalClass foo;  // global variable / object; give it a memory space to live

void doSomething( void )
{
  foo.bar();      // use the global foo object
}

int main( int argc, const char *argv[] )
{
  foo( argc );   // foo can only be instantiated in main as it's using
                 // information that's only available here

  doSomething(); // use the global foo object

  return 0;
}

如您所见,foo具有全局范围 - 但要调用其构造函数,我需要一些仅在main内可用的信息。

我该如何实现?

我能解决的唯一解决方案是使foo指向globalClass - 但每次我使用foo时都会导致指针解除引用。在紧密循环中使用时,这可能会产生性能问题...

PS:在真实程序中maindoSomething将存在于不同的文件中。当然,保证foo在实例化之前不会被访问。

3 个答案:

答案 0 :(得分:5)

如何在函数中使用foo作为static变量?这样,它只在调用函数时被实例化:

globalClass& getThing()
{
  static globalClass thing;
  return thing;
}

void doSomething(const globalClass& thing);

int main()
{
  const globalClass& x = getThing();
  doSomething(x);  
}

答案 1 :(得分:5)

如上所述使用指针是最简单,最干净的事情。指针取消引用的开销并不是那么多。除非你真的证明了开销是显而易见的,否则我建议使用它。

您的第二个选择是将globalClass的构造和初始化分成两个单独的方法。构造函数只会执行不需要外部信息的最简单的事情,并且您可以调用init(argc)main内的任何内容来合并外部信息。

您还可以使用分配来初始化foo,例如:

globalClass foo;

int main(int argc, const char *argv[]) {
    globalClass bar(argc);
    foo = bar;
}

主要使用临时变量进行初始化,然后复制结果。

答案 2 :(得分:0)

如果您不想要间接,并且不介意自己进行清理,那么这是一个非常可怕的黑客攻击:

union ClassHolder
{
    globalClass x;
    char buf[sizeof globalClass];

    constexpr ClassHolder() noexcept : buf() { }
};

ClassHolder h;
globalClass & foo = h.x;

int main()
{
    new (static_cast<void *>(&h.x)) globalClass(arg1, arg2, arg3);

    // main program

    h.x.~globalClass();
}