在下面的程序中,我在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?
答案 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 未存储在堆中,因此它创建问题。