12

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

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在实例化之前不会被访问。

4

3 回答 3

6

foo在函数内部作为static变量怎么样?这样,它只会在调用函数时被实例化:

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

void doSomething(const globalClass& thing);

int main()
{
  const globalClass& x = getThing();
  doSomething(x);  
}
于 2012-12-01T23:49:25.810 回答
5

正如您提到的那样使用指针是最简单和最干净的事情。指针取消引用的开销实际上并没有那么多。我建议使用它,除非你真的证明开销是明显的。

您的第二个选择是将构造和初始化globalClass分离为两个单独的方法。构造函数只会做不需要外部信息的最简单的事情,你会调用init(argc)或内部main的任何东西来合并外部信息。

您还可以使用赋值来初始化 foo,例如:

globalClass foo;

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

这本质上是使用临时变量进行初始化,然后复制结果。

于 2012-12-01T23:53:05.907 回答
1

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

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();
}
于 2012-12-02T00:15:05.320 回答