哇,我不敢相信没有人提到最明显的答案,并且最接近模仿 C# 的静态构造函数行为的答案,即在创建该类型的第一个对象之前不会调用它。
std::call_once()
在 C++11 中可用;如果您不能使用它,可以使用静态布尔类变量和比较和交换原子操作来完成。在您的构造函数中,查看是否可以将类静态标志从 原子 更改false
为true
,如果可以,您可以运行静态构造代码。
为了获得额外的荣誉,请将其设置为 3 路标志而不是布尔值,即未运行、正在运行和已完成运行。然后该类的所有其他实例可以自旋锁定,直到运行静态构造函数的实例完成(即发出内存栅栏,然后将状态设置为“完成运行”)。你的自旋锁应该执行处理器的“暂停”指令,每次等待加倍直到达到阈值,等等——非常标准的自旋锁技术。
在没有 C++11 的情况下,这应该可以帮助您入门。
这里有一些伪代码来指导你。把它放在你的类定义中:
enum EStaticConstructor { kNotRun, kRunning, kDone };
static volatile EStaticConstructor sm_eClass = kNotRun;
这在你的构造函数中:
while (sm_eClass == kNotRun)
{
if (atomic_compare_exchange_weak(&sm_eClass, kNotRun, kRunning))
{
/* Perform static initialization here. */
atomic_thread_fence(memory_order_release);
sm_eClass = kDone;
}
}
while (sm_eClass != kDone)
atomic_pause();