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

这两个问题是相关的。我相信答案对您来说并不清楚,因为staticC++ 中的关键字具有重载含义。

当您在函数内定义静态变量时,您实际上是在告诉编译器仅在第一次调用时对其进行初始化(因此您可以在多次调用中使用该值)。这与文件范围或类范围静态变量的情况并不完全相同。

考虑到这一点,在本地类中定义静态变量可能没有意义,而本地类又在函数中定义。

关于您的第二个问题,本地类实际上可以访问在其封闭函数中定义的静态变量。例如,下面的代码应该在符合标准的编译器中编译。


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

不能在封闭范围内检查堆栈变量的另一个原因是本地类中的函数不一定直接从封闭函数调用。

hello()在下面的示例中,如果是类中唯一的函数,生活会很容易: 要找到变量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 回答