20

静的メンバー関数で作成されたオブジェクトと変数は、メンバー関数の場合のように「ローカル」とは見なされないため、複数のスレッド間で共有できるようになりました。

一方、オブジェクトを作成するメンバー関数がある場合、これはスレッドに対してローカルであるため、非共有になります。

私はこれを言うのは正しいですか?

4

4 に答える 4

45

このクラスを検討してください

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);
}

それが役立つことを願っています。

于 2011-01-06T18:48:19.013 に答える
24

いいえ、あなたは正しくありません。

静的関数で作成されたオブジェクトは共有されません。これは通常の関数にも当てはまります。

オブジェクト自体が静的であると宣言されている場合でも、オブジェクトを共有できます。関数が静的であるかどうかに依存しません。

void myFunc()
{
    static MyObject o;
    o.CallMethod(); // here o is shared by all threads calling myFunc
}

オブジェクトが静的であると宣言されると、オブジェクトはグローバル変数であるかのように見えますが、宣言されている関数のスコープ内でのみ表示されます。

于 2011-01-06T16:37:19.730 に答える
3

いいえ、あなたは正しくありません。はい、C++ は「静的」という言葉を多用しています。

もちろん、静的クラス メンバー変数は、クラスが名前空間スコープとして機能するグローバルであり、プライベートまたはプロテクト (クラスによってのみアクセス可能) である場合は、アクセス権限に多少の違いがあります。

ただし、静的クラス メンバー関数は通常のフリー関数 (クラス メンバーではない) と同様であり、呼び出されるたびに独自のローカル変数を持ちます。

命名規則を除けば、静的クラス メンバー関数と通常の自由関数の唯一の実際の違いは、クラスのプライベート メンバーにアクセスできることです (そして、そのメンバーの外部「インスタンス」が必要です)。

さらに、可変テンプレート パラメーターを使用してテンプレートから静的クラス メンバー関数を呼び出すことができます。これは、一般に「コンパイル時ポリモーフィズム」と呼ばれ、メタプログラミングで一般的に使用されるものを呼び出します。

任意の関数内の静的な「ローカル」変数は単一インスタンスですが、一方でグローバル変数にも少し似ており、関数を呼び出す 2 つのスレッドが同じインスタンスにアクセスするため、スレッド競合の問題に敏感です。

于 2011-01-06T16:37:09.890 に答える
1

関数が静的かどうかは関係ありません (クラス メソッド)。自動変数のみが関数のローカルとして表示されます。それらのデータのアドレスを知っている場合は、アクセスできます。

たとえば、スレッド ローカル ストレージを使用して、出力を専用のスレッド コンテキストに割り当てることができます。

于 2011-01-06T16:36:12.677 に答える