2009-04-29 10 views
0

コードC++クラスでキーワード "static"を使用するのはいつですか?私たちはクラスのstaticを使用すべき状況では

static void MyClass::ThreadEntryStatic() 
{ 
    //... 
} 

void MyClass::Begin() 
{ 
     CreateThread(..,ThreadEntryStatic,..); 
} 

+2

このスレッド関連の質問やC++質問ですか? – Tom

+3

この質問のタイトルは誤解を招くものです。スレッディングと何かを加えることで事態を明らかにするかもしれません。 –

+0

スレッドに関してはどうですか?ユーザは静的関数の概念をはっきりと理解していない。スレッドライブラリーが静的関数を使用する必要があるという事実はおそらく質問にハイライトされています.... – jheriko

答えて

4

staticというキーワードを使用できる場所は3つあります。その文脈がメソッドがインスタンスメソッドではなくクラスメソッドであることを意味する場合、struct/classの宣言に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

複数のスレッドで静的メソッドを実行する場合は、コードの同期に非常に注意を払う必要があります。私の考えでは、マルチスレッドプログラミングでは、スレッドごとにオブジェクトまたはワークアイテムのインスタンスを別々に使用し、すべてのタイプの静的または共有データをまったく使用しないようにします。もちろんこれは常に可能なわけではないので、スレッディングは扱う最も面倒なプログラミング領域の1つです。

+0

これは静的メソッドの問題ではなく、静的データメンバーの問題です。静的でないクラスメソッドもすべてアクセスできます。 – sharptooth

0

静的変数の値は、関数呼び出しの間に保持されます。例についてはthis MSDNのエントリを確認してください。静的メソッドの定義と使用については、chrishの回答で概説されています

スタティックは、クラスのインスタンスを1つだけ持つ必要があるシングルトンクラスを実装するときに使用できます。 その使い方はコンテキストによって異なります。

1

具体例としては、

class Test{ 
     static void foo();  
}; 

static void Test::foo(){ 
    // code here 
} 

を使用すると、クラス宣言の外でstaticキーワードで関数を宣言することはできません、コンパイルするつもりはありません。関数を実装するときは、staticキーワードを削除するだけです。

class Test{ 
     static void foo();  
}; 

void Test::foo(){ 
    // code here 
} 
1

代わりに1が匿名の名前空間を使用する必要があり、少数の人々がこれに触れているが、内部結合のために使用さstaticは使用すべきではありません。

namespace 
{ 

void myInternallyLinkedFunction() 
{ 
    // do something 
} 

int myInternallyLinkedInteger; 

class myInternallyLinkedClass 
{ 
public: 
    void doSomething(); 
}; 

} // anon namespace 


void myExternallyLinkedFunction() 
{ 

    ++myInternallyLinkedInteger; 
    myInternallyLinkedFunction(); 
    myInternallyLinkedClass x; 
    x.doSomething(); 
} 
0

は、どのようなあなたの例が示すことは、「静的メンバであります関数スレッドコールバック "パターンを使用します。スレッド関数は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, ...); 
    } 

}; 
関連する問題