在 C++ 的 main() 函数中声明 class

Declared class inside the main() function in C++

在下面的程序中,我在 main() 函数中声明了 class。

案例 1:

int main()
{
        static int i = 10; // static variable

        class A
        {
        public:
                A()
                {
                    std::cout<<i;
                }
        };
        A a;
        return 0;
}

并且它在 G++ 编译器中运行良好。

但是,如果我删除 static 关键字并编译它,编译器会报错。

案例二:

int main()
{
        int i = 10; // removed static keyword

        class A
        {
        public:
                A()
                {
                    std::cout<<i;
                }
        };
        A a;
        return 0;
}

错误:

 In constructor 'main()::A::A()':
13:32: error: use of local variable with automatic storage from containing function
:cout<<i;
                                ^
7:13: note: 'int i' declared here
         int i = 10;
             ^

为什么案例 1 工作正常?为什么情况 2 不起作用?

为什么不起作用?

Copy/paste 来自 https://www.quora.com/Why-cant-local-class-access-non-static-variables-of-enclosing-function

You are wondering about a variable outside of a class. I will explain this the none-C++ way. Let's look at it from the paradigm of general machine architecture and the way programming languages are oft defined. The issue is stack frames, the concept of the stack, and how program refer to memory locations.

When a function is called, the variables of that function are pushed onto the stack. A function and its variables are often a sequence of memory locations. When the function is finished, it and those variables are popped off the stack. That means when the function is called, variables come into existence. When the function is done, the variables depart immediately. Each variable, like the function itself are memory locations (may be assigned to registers).

Declaring the class does not declare a variable. The class is just a definition in the world of C++ and has no linkage to the variable defined in the outer scope. The phrase, automatic storage duration, is roughly synonymous with the idea of the variable (memory) automatically recovered when the function exits. Even though it is C++, when it compiles, it is still machine language and will obey the rules of the machine. The method you called on the class is part of the class but is not part of the function. Only the class definition is local to the function.

All functions, regardless of where they exist are their own stack frame. The standard way stack frames are done means, unless the memory location referenced is valid, the data will be inaccessible by the time the function in the class is called. In this case, it isn't because the variable in the outer scope has been reclaimed, but because when the method in the class is called, the stack frame in which the outer variable exists is not active in the series of registers used by the method being called. The compiler was encoded with the understanding of this process and gave an error message to ward off the trouble that would ensue if such access was attempted.

You can still access the variable if you affix the static keyword to the variable. That is mentioned in the web page Local Classes in C++ that has the same code example you have listed. Basically, you have to extend the storage duration or the duration that the memory for the variable remains valid in the enclosing scope. Generally, a good way to think through these kind of error messages is through knowledge of the language specification, but in terms of time, relating the representations back to machine architecture can zero in on the underlying reasons why.

如何解决?

只需将您想要在 class 内部使用的变量作为参数传递给构造函数(我已将其设为引用成员,因此 i 中的更改将可见也在 class 内部,但请注意,一旦函数退出,i 将超出范围):

#include<iostream>

int main()
{
  int i = 10; // static variable

  class A
  {
  private:
    int &r_i;
  public:
    A(int &i)
    :
      r_i(i)
    {
      std::cout<<r_i;
    }
  };
  A a(i);
  return 0;
}

我不确定如果我错了请纠正我,这可能是因为静态变量和 class 都存储在堆中因此情况 1 工作正常,而情况 2 作为变量 i 是未存储在堆中会造成问题。