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

时间:2017-05-12 07:51:10

标签: c++ class static main

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

案例1:

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

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

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

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

案例2:

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?

2 个答案:

答案 0 :(得分:4)

为什么它不起作用?

复制/粘贴 https://www.quora.com/Why-cant-local-class-access-non-static-variables-of-enclosing-function

  

你想知道一个类之外的变量。我会解释   这是非C ++方式。让我们从一般范式来看待它   机器架构和编程语言的方式   定义。问题是堆栈帧,堆栈的概念以及如何   程序指的是内存位置。

     

调用函数时,会推送该函数的变量   到堆栈上。函数及其变量通常是一系列的   记忆位置。当功能完成时,它和那些   变量从堆栈中弹出。这意味着功能何时   被称为变量的存在。当功能完成后,   变量立即离开。每个变量,就像函数本身一样   是存储位置(可以分配给寄存器)。

     

声明该类不声明变量。这堂课只是一个   在C ++世界中的定义并没有与变量的链接   在外部范围内定义。短语,自动存储持续时间,是   大致与变量(内存)的概念同义   函数退出时自动恢复。尽管如此   C ++,当它编译时,它仍然是机器语言并且将遵守   机器的规则。你在课堂上调用的方法是其中的一部分   类但不是函数的一部分。只有类定义   是函数的本地。

     

所有函数,无论它们存在于何处,都是它们自己的堆栈   帧。标准方式堆栈帧完成意味着,除非内存   引用的位置有效,数据将无法访问   调用类中的函数的时间。在这种情况下,它不是   因为外部范围中的变量已被回收,但是   因为当调用类中的方法时,堆栈框架在   外部变量存在的系列中没有活动的   被调用方法使用的寄存器。编译器已编码   了解这个过程并给出了错误信息   避免在尝试进行此类访问时可能发生的麻烦。

     

如果您将static关键字添加到,则仍可以访问该变量   变量。这在网页中提到了C ++中的Local Classes   与您列出的代码示例相同。基本上,你必须   延长存储持续时间或存储器的持续时间   变量在封闭范围内保持有效。一般来说,一个好方法   通过这些错误信息来思考是通过知识   语言规范,但在时间方面,与之相关   回到机器架构的表示可以归零   潜在的原因。

如何解决这个问题?

只需将您想要在类中使用的变量作为构造函数的参数传递(我已将其作为参考成员,因此i中的更改将在该类也是如此,但请注意,一旦函数退出,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;
}

答案 1 :(得分:-1)

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