コンストラクター内の静的変数、欠点や副作用はありますか?
-
05-10-2019 - |
質問
私がやりたいこと:クラスのインスタンスがプログラム内で使用されるたびに、いくつかの前提条件コードを実行します。このコードは、要件などをチェックし、1回だけ実行する必要があります。
これは、コンストラクター内の静的変数として別のオブジェクトを使用して達成できることがわかりました。これがより良い写真の例です:
class Prerequisites
{
public:
Prerequisites() {
std::cout << "checking requirements of C, ";
std::cout << "registering C in dictionary, etc." << std::endl;
}
};
class C
{
public:
C() {
static Prerequisites prerequisites;
std::cout << "normal initialization of C object" << std::endl;
}
};
私を悩ませているのは、これまでのところ、静的変数の同様の使用を見ていないということです。欠点や副作用はありますか、それとも何かが足りませんか?それとも、より良い解決策があるかもしれませんか?どんな提案でも大歓迎です。
解決
2つのスレッドが同時に初めてCを構築しようとする場合、前提条件はおそらく2回初期化されるため、これはスレッドセーフではありません。
それで大丈夫なら、おそらくこれを行うことができますが、Scoped Constructor Systemのゲームには発見可能性がゼロになります(つまり、「トリック」を忘れた場合、または他の人がコードを読み取ろうとすると、彼らは何が起こっているのかについて困惑します)。
他のヒント
欠点や副作用はありますか、それとも何かが足りませんか?それとも、より良い解決策があるかもしれませんか?どんな提案でも大歓迎です。
静的な方法を明示的に呼び出すことはより明確であるかもしれません(より冗長ですが)。
class Prerequisites
{
static bool checkedOnce;
public:
static void checkOnce() {
if (checkedOnce)
{
//already checked: don't check again
return;
}
//else check them now
checkedOnce = true;
std::cout << "checking requirements of C, ";
std::cout << "registering C in dictionary, etc." << std::endl;
}
};
bool Prerequisites::checkedOnce = false;
class C
{
public:
C() {
Prerequisites::checkOnce();
std::cout << "normal initialization of C object" << std::endl;
}
};
少なくとも、前提条件クラス内のMutexと静的フラグを使用して、前提条件オブジェクトの複数の初期化を保護する必要があります。そのようにして、あなたのコードはスレッド安全になります。
所属していません StackOverflow