静的メンバー関数で作成されたオブジェクトと変数は、メンバー関数の場合のように「ローカル」とは見なされないため、複数のスレッド間で共有できるようになりました。
一方、オブジェクトを作成するメンバー関数がある場合、これはスレッドに対してローカルであるため、非共有になります。
私はこれを言うのは正しいですか?
静的メンバー関数で作成されたオブジェクトと変数は、メンバー関数の場合のように「ローカル」とは見なされないため、複数のスレッド間で共有できるようになりました。
一方、オブジェクトを作成するメンバー関数がある場合、これはスレッドに対してローカルであるため、非共有になります。
私はこれを言うのは正しいですか?
このクラスを検討してください
class CData
{
public:
static void func()
{
int a;
static int b;
}
int c;
static int d;
};
int main()
{
CData::func();
}
現在、 variablea
は の各呼び出しに対してローカルですfunc()
。func()
2 つのスレッドが同時に呼び出すと、異なるバージョンのa
.
b
静的ローカルです。値は、 の異なる呼び出し間で保持されますfunc()
。2 つのスレッドが同時に呼び出すfunc()
と、同じバージョンの にアクセスするb
ため、同期が必要になる場合があります。
c
インスタンス変数です。これは、CData の特定のインスタンス化に関連付けられています。 以下に示すトリックを使用しない限り、 に func()
アクセスできません。c
d
静的変数です。クラス CData のすべての使用間で shared のインスタンスが 1 つあるd
ため、同期が必要になる場合があります。静的関数から簡単に使用できますfunc()
。
静的関数からインスタンス データにアクセスするために使用されるトリックは、有効なオブジェクトを関数に渡すことです。
例えば
class CData
{
public:
static void func(CData *p)
{
int a;
static int b;
b = p->c;
}
int c;
static int d;
};
int main()
{
CData data;
CData::func(&data);
}
それが役立つことを願っています。
いいえ、あなたは正しくありません。
静的関数で作成されたオブジェクトは共有されません。これは通常の関数にも当てはまります。
オブジェクト自体が静的であると宣言されている場合でも、オブジェクトを共有できます。関数が静的であるかどうかに依存しません。
void myFunc()
{
static MyObject o;
o.CallMethod(); // here o is shared by all threads calling myFunc
}
オブジェクトが静的であると宣言されると、オブジェクトはグローバル変数であるかのように見えますが、宣言されている関数のスコープ内でのみ表示されます。
いいえ、あなたは正しくありません。はい、C++ は「静的」という言葉を多用しています。
もちろん、静的クラス メンバー変数は、クラスが名前空間スコープとして機能するグローバルであり、プライベートまたはプロテクト (クラスによってのみアクセス可能) である場合は、アクセス権限に多少の違いがあります。
ただし、静的クラス メンバー関数は通常のフリー関数 (クラス メンバーではない) と同様であり、呼び出されるたびに独自のローカル変数を持ちます。
命名規則を除けば、静的クラス メンバー関数と通常の自由関数の唯一の実際の違いは、クラスのプライベート メンバーにアクセスできることです (そして、そのメンバーの外部「インスタンス」が必要です)。
さらに、可変テンプレート パラメーターを使用してテンプレートから静的クラス メンバー関数を呼び出すことができます。これは、一般に「コンパイル時ポリモーフィズム」と呼ばれ、メタプログラミングで一般的に使用されるものを呼び出します。
任意の関数内の静的な「ローカル」変数は単一インスタンスですが、一方でグローバル変数にも少し似ており、関数を呼び出す 2 つのスレッドが同じインスタンスにアクセスするため、スレッド競合の問題に敏感です。
関数が静的かどうかは関係ありません (クラス メソッド)。自動変数のみが関数のローカルとして表示されます。それらのデータのアドレスを知っている場合は、アクセスできます。
たとえば、スレッド ローカル ストレージを使用して、出力を専用のスレッド コンテキストに割り当てることができます。