C 公共变量范围混乱

C++ public variable scope confusion

本文关键字:范围 混乱 变量      更新时间:2023-10-16

如果您在类中声明公共变量,则可以从也是该类的成员的任何函数中修改该变量。

如果您在函数中声明一个变量,则其范围不会超过函数的范围。

那么,公共类变量本质上是一个可以由类的任何成员访问和更改的全局变量?

如果是这样,全球变量和公共变量有什么区别?

您缺少的更重要的语义是类成员变量(除非是 static(特定于该类别的每个实例。例如

class Foo
{
public:
    Foo() = default;
    int x;
};

如果我说

Foo a{};
Foo b{};
a.x = 1;
b.x = 7;
a.x != b.x;   // value is different
&a.x != &b.x  // address is different

请注意,成员变量x具有不同的值,具有不同的地址(因为它是完全不同的int(,并且属于Foo的每个实例。

现在关于static的提及,请注意我不能这样做

Foo::x = 5;   // only works if x is static

因为我需要Foo的实际实例,以访问其成员变量。而是static成员不需要实例,并且整个类都有该成员的一个实例。

如果您在类中声明公共变量,则可以从该类也是该类成员的任何函数中修改该变量。

不是完全:这也适用于私人和受保护的变量。也就是说,如果一个类有3个变量,则其中一个是public,一个protected和一个private,则该类的函数不仅可以修改公共一个。相反,他们可以修改所有3.作为同一班级的成员为您提供最高的权限。当试图从外部操纵这些变量时,可以看到这三个访问修饰符之间的差异:从任何地方到达 :公共变量可从任何地方到达,可以从同一类和从其派生的类中达到保护变量(如果有(,并且私人只能从同一班级的其他成员到达。

如果您在函数中声明一个变量,则其范围不会超过函数的范围。

是的,这实际上也适用于任何块:如果您在for循环中声明一个变量,则其范围将是循环。功能只是一种块。

那么,公共类变量本质上是一个可以由类的任何成员访问和更改的全局变量?

否,正如我在上面说的那样,任何 aish 类的成员都可以访问一个公共类变量,甚至可以从根本不属于任何类别的东西中访问:这正是含义的含义"公共"。

如果是这样,全球变量和公共变量有什么区别?

正如Corykramer在他的回答中所说的那样,班级成员生活在一个对象中,并且对象彼此独立,因此,如果您创建同一类的10个对象,则所有10个将拥有自己的该变量的副本。static类成员是一个例外,因为它们是由类的所有对象共享的,实际上甚至不需要一个对象(您熟悉singleton的概念?没有静态成员,它都无法正常工作(。

一个实际的区别:假设您想将文件的名称存储在可以从所有功能中易于访问的地方。全球会做。相反,班级的公共成员要求您首先创建该类的对象,然后该对象必须在范围内!如果您在main()中创建对象,然后您想从称为write_results_to_file()的函数读取该变量,以便您知道要写入哪个文件,则必须注意将对象传递到该函数,否则该对象将退出尽管公开了,范围和公共成员仍无法实现。

因此,全球变量更加方便,因为它们需要更少的工作。这正是人们喜欢使用它们的原因,但是请注意,这种懒惰会带来不良代码:如果您使用全局变量,编写代码更容易,但是很难理解每个函数的工作原理。理想情况下,功能仅需要其参数,然后可以运行并产生结果。在C 中,通常您可以通过在.HH文件中查看其声明来查看函数的参数。但是,如果该函数访问了全局变量,我们可以说该函数使用"隐藏"参数,其中"隐藏"意味着它在声明中没有显示。一旦程序生长到非平凡的规模,这实际上会使事情变得更加困难,因为很难理解变化的后果。例如,如果程序修改了全局变量,则使用该变量的所有函数都会受到影响,但是在某些情况下,它根本不会显而易见,这将导致很难找到的细微错误。举一个例子,测试函数可能会变得更加困难:如果您编写一些测试用例,只要您通过的参数相同,就会期望每次运行它们,就会获得相同的结果。相反,结果将取决于参数(清楚(,也取决于全局变量的价值(这并不明显(。

这就是为什么全局变量被皱眉的原因:因为它们使编写代码变得容易快速,但是很难理解并维护它(添加新功能或修复错误(。使用它们不禁止,但您应该仔细且谨慎地进行。