4

ローカル クラス内でメンバー変数を宣言できないことはわかっていstaticますが、その理由は明らかではありません。

では、誰か説明してください。

staticまた、ローカル クラスが定義されている関数内で定義された非変数に、ローカル クラス メンバー関数で直接アクセスできないのはなぜですか。

以下のコードでは:

int main(int argc, char *argv[])
{
    static size_t staticValue = 0;

    class Local
    {
         int d_argc; // non-static data members OK
         public:
         enum // enums OK
         {
             value = 5
         };
         Local(int argc) // constructors and member functions OK
         : // in-class implementation required
          d_argc(argc)
         {
               // global data: accessible
               cout << "Local constructor\n";
               // static function variables: accessible
               staticValue += 5;
         }
         static void hello() // static member functions: OK
         { 
            cout << "hello world\n";
         }
   };
   Local::hello(); // call Local static member
   Local loc(argc); // define object of a local class.
   return 0;
}

staticValue一方、静的変数は直接アクセスできますが、argc引数 frommainはそうではありません....

4

6 に答える 6

4

2つの質問は関連しています。staticC ++のキーワードの意味がオーバーロードされているため、答えは明確ではないと思います。

関数内で静的変数を定義すると、実際には、最初の呼び出しでのみ初期化するようにコンパイラーに指示します(したがって、複数の呼び出しで値を使用できます)。これは、ファイルスコープまたはクラススコープの静的変数の場合とまったく同じではありません。

これを念頭に置いて、ローカルクラス内で静的変数を定義することは意味がないかもしれません。ローカルクラスは関数内で定義されます。

2番目の質問に関して、ローカルクラスは、実際には、それを囲む関数で定義された静的変数にアクセスできます。たとえば、以下のコードは、標準に準拠したコンパイラでコンパイルする必要があります。


void f()
{
  static int i;
  class local
  {
    int g() { return i; }
  };

  local l;
  /* ... */
}

int main()
{
  f();
  return 0;
}
于 2010-01-06T12:51:24.180 に答える
4
  1. ローカル クラスの静的変数/関数: 構文、有効期間の定義、名前マングリングの実装を想像してみてください。私はすぐにあきらめます:)
  2. ローカル クラスからローカル変数にアクセスできません: クラス インスタンスが関数スコープより長く存続する可能性があるためです。例:
    class interface; // base class declared somewhere
    
    // creates specific implementations
    interface* factory( int arg ) // arg is a local variable
    {
      struct impl0: interface { /* ... */ }; // local class
      struct impl1: interface { /* ... */ }; // local class
      // ...
    
      switch ( arg )
      {
        case 0: return new impl0;
        case 1: return new impl1;
        // ...
      }
    
      return 0;
    }
    ローカルに宣言されたクラス インスタンスは、関数のローカル変数の寿命を超えて存在するようになります。
于 2010-01-06T13:32:33.753 に答える
3

ローカルクラスは環境への完全なアクセス権を持っていません (リチャードに感謝します)...例えば参照やポインタを使用してそれを回避する必要があります:

void f() {
    int i = 0;

    struct local {
        int& i;
        local(int& i) : i(i) {}
        void f() { i = 1; }
    };

    local l(i);
    l.f();
    assert(i==1);
}
于 2010-01-06T12:20:23.483 に答える
1

外側のスコープでスタック変数を調べられないもう 1 つの理由は、ローカル クラスの関数が外側の関数から直接呼び出されるとは限らないことです。

以下の例ではhello()、 がクラス内の唯一の関数である場合は簡単です。 variable を見つけるにはstackValuehello()呼び出し元のスタック フレームを調べるだけで済みます。Local::goodbye()しかし、ここでは、を呼び出す場合としない場合がある を紹介しましたLocal::hello。この場合、Local::hello()囲んでいる関数のスタック フレームを見つける場所をどのように知るのでしょうか? (これを機能させるにはクロージャーが必要です。私はクロージャーが大好きですが、C++ でそれが起こっているのを見ることができません。)

int main(int argc, char *argv[])
{
    static size_t staticValue = 0;
    int size_t stackValue = argc;

    class Local
    {
         void hello() 
         { 
            cout << "stackValue is " << stackValue << "\n";
         }
         void goodbye()
         {
            if (stackValue == 42) {
                hello();
            }
            else {
                cout << "Goodbye!\n";
            }
         }
   };
   Local loc;
   loc.hello();
   stackValue = 42;
   loc.goodbye();
   return 0;
}
于 2010-01-06T13:42:22.360 に答える
0

ローカル クラスが静的メンバー (またはクラスの外部で定義された関数) を持つことができない理由は、意味上の理由よりも構文上の理由によるものだと思います。静的メンバーは、非ローカル クラスと同じように実装できます。静的メンバーは、関数内で宣言された静的変数と同様に、関数への最初の呼び出しから始まる有効期間を持ちます。コンパイラは、クラスの最初のインスタンスが作成されたときに静的メンバーが初期化されていることを確認する必要があります。

囲んでいる関数のシグネチャが名前の一部になった今、名前マングリングの問題を想像してみてください。;-)

ローカル クラス内の関数のローカル変数またはパラメーターにアクセスできない理由は、クラスを実装するために必要なコードが複雑になり、メリットがほとんどないためです。クラスの非静的メンバーは、通常、"this" ポインターまたは特定のインスタンスへのポインターを介してアクセスされます。囲んでいる関数にローカルな変数とパラメーターにアクセスするには、それらにアクセスできるようにする何らかのメカニズムが必要になります。関数がインライン化されていれば、そのメカニズムはかなり簡単かもしれませんが、インライン化されていない場合はどうなりますか?

于 2010-01-06T13:13:09.933 に答える
0

静的変数は、プログラムの開始時に初期化されます。メソッドが呼び出されると、ローカル クラスが読み込まれます。メソッド呼び出しが終了するとアンロードされます。

ウィキペディアによると

コンピューター プログラミングでは、静的変数は静的に割り当てられた変数であり、その有効期間はプログラムの実行全体に及びます。

これは、静的変数が宣言されているローカル クラスのロードとアンロードとは対照的です。

于 2010-01-06T12:33:00.693 に答える