うわー、私は誰も最も明白な答えを述べたとは信じられません。C#の静的コンストラクタの動作を最もよく模倣したもの、つまり、その型の最初のオブジェクトが作成されるまで呼び出されません。
std::call_once()
C ++ 11で利用可能です。それを使用できない場合は、静的なブールクラス変数と比較および交換のアトミック操作を使用して実行できます。コンストラクターで、クラス静的フラグをからfalse
にアトミックに変更できるかどうかを確認します。変更できるtrue
場合は、静的構成コードを実行できます。
追加のクレジットについては、ブール値ではなく、3ウェイフラグにします。つまり、実行、実行、実行を終了しません。次に、そのクラスの他のすべてのインスタンスは、静的コンストラクタを実行しているインスタンスが終了するまでスピンロックできます(つまり、メモリフェンスを発行し、状態を「実行中」に設定します)。スピンロックは、プロセッサの「一時停止」命令を実行し、しきい値になるまで毎回2倍待機する必要があります。これはかなり標準的なスピンロックテクニックです。
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();