キーワード“ static”を使用する場合C ++クラスで?
-
03-07-2019 - |
質問
コード
static void MyClass::ThreadEntryStatic()
{
//...
}
void MyClass::Begin()
{
CreateThread(..,ThreadEntryStatic,..);
}
クラスでstaticを使用する条件は?
解決
staticキーワードを使用できる場所は3つあります。 1つは、そのコンテキストがメソッドがインスタンスメソッドではなくクラスメソッドであることを意味する場合、構造体/クラスの宣言にあります。つまり、このメソッドは直接呼び出され、インスタンスは必要ありません。この静的メソッドからは、インスタンス変数にアクセスできません。
MyClass.hで
struct MyClass
{
static void ThreadEntryStatic();
void Begin();
};
MyClass.cppで
void MyClass::ThreadEntryStatic()
{
}
void MyClass::Begin()
{
CreateThread(.., MyClass::ThreadEntryStatic, ...);
}
staticキーワードが使用される2番目のケースは、宣言された変数の可視性をファイルの外部で可視にしたくないファイルのスコープ内です。これにも匿名の名前空間を使用できます。
staticキーワードが使用される3番目のケースはメソッドのスコープ内にあり、値は関数の実行間で保持されます(そして最初に割り当てで初期化されます)。
他のヒント
複数のスレッドで静的メソッドを実行している場合、コードの同期に細心の注意を払う必要があります。私の意見では、マルチスレッドプログラミングを行うときは、スレッドごとにオブジェクトまたはワークアイテムの個別のインスタンスを使用し、静的データや共有データを一切使用しないようにします。もちろん、これは常に可能であるとは限らないので、スレッド処理は依然として最も扱いにくいプログラミング領域の1つです。
具体例として、
class Test{
static void foo();
};
static void Test::foo(){
// code here
}
はコンパイルされません。クラス宣言の外部で静的キーワードを使用して関数を宣言することはできません。関数を実装するときに、静的キーワードを削除するだけです。
class Test{
static void foo();
};
void Test::foo(){
// code here
}
これに触れた人は少数ですが、内部リンクに使用される static
は使用しないでください。代わりに匿名の名前空間を使用する必要があります。
namespace
{
void myInternallyLinkedFunction()
{
// do something
}
int myInternallyLinkedInteger;
class myInternallyLinkedClass
{
public:
void doSomething();
};
} // anon namespace
void myExternallyLinkedFunction()
{
++myInternallyLinkedInteger;
myInternallyLinkedFunction();
myInternallyLinkedClass x;
x.doSomething();
}
静的変数の値は、関数呼び出し間で保持されます。例については、 this MSDNエントリを確認してください。 「静的」を定義して使用するメソッドはchrishの答えで概説されています
静的は、クラスのインスタンスを1つだけ持つ必要があるシングルトンクラスを実装するときに使用できます。 使用法はコンテキストに依存します。
例が示すのは、「静的メンバー関数スレッドコールバック」です。パターン。スレッド関数にはWINAPI署名が必要であるため、通常のメンバー関数にすることはできず、静的メンバーのみにすることができます。多くの場合、これをスレッドパラメーターとしてこのコールバックに渡し、スレッド処理を実行する実際のメンバーを呼び出します。
静的メンバーの使用は1つだけで、さまざまな方法があります。あなたの質問の目的が何であるかを推測することは本当に難しいです。特定の問題を解決していますか、それとも静的メンバーまたは静的メンバー関数のすべての可能な使用法に興味がありますか?
「静的メンバー関数スレッドコールバック」のより完全な例:
class MyClass
{
/// background rendering thread
int ThreadEntry()
{
// do the work here
}
/// static member callback "proxy"
static DWORD WINAPI ThreadEntryStatic(void *param)
{
return ((EngineDD9 *)param)->ThreadEntry();
}
void SpawnThread()
{
CreateThread(.., ThreadEntryStatic, ...);
}
};