我有代码,其中必须通过相当多的代码来设置全局资源:
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:在真实程序中main
和doSomething
将存在于不同的文件中。当然,保证foo
在实例化之前不会被访问。
答案 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();
}