C ++公共变量范围混乱

时间:2017-06-01 21:42:37

标签: c++ scope global-variables difference public-members

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

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

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

如果是这样的话,那么全局变量和公共变量之间的区别是什么?

2 个答案:

答案 0 :(得分:5)

您缺少的更重要的语义是类成员变量(除非它是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成员不需要实例,整个类只有一个共享该成员的实例。

答案 1 :(得分:2)

  

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

不完全相同:同样适用于私有变量和受保护变量。也就是说,如果一个类有3个变量,其中一个是public,一个protected和一个private,那么该类成员的函数不仅可以修改公共变量。 ;相反,他们可以修改所有3.作为同一个类的成员给你最高的权限。当尝试从外部那个类操作那些变量时,可以看到这三个访问修饰符之间的区别:公共变量可以从任何地方到达,受保护变量可以从同一个类和从它派生的类到达(如果有的话,只能从同一类的其他成员那里获得私人的。

  

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

是的,并且实际上同样适用于任何块:如果在for循环内声明变量,则其范围将是循环。函数只是一种块。

  

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

不,正如我上面所说的,任何类的成员可以访问公共类变量,甚至可以从完全不属于任何类的东西访问:这正是“公共”。

  

如果是这样的话,全局变量和公共变量之间有什么区别?

正如CoryKramer在his answer中所说,一个类成员生活在一个对象中,并且对象彼此独立,所以如果你创建10个同一个类的对象,那么所有10个对象都有自己的变量副本。 static类成员是一个例外,因为它们由类的所有对象共享,实际上甚至不需要存在单个对象(您是否熟悉Singleton的概念?没有静态成员就行不通。)

实际差异:假设您希望将文件名存储在可以从所有功能轻松访问的位置。一个全球意志。相反,类的公共成员要求您首先创建该类的对象,然后该对象必须在范围内!如果在main()中创建对象,然后想要从名为write_results_to_file()的函数中读取该变量,以便知道要写入哪个文件,则必须注意将对象传递给该函数,否则该对象将超出范围,公共成员将无法访问,尽管是公开的。

因此,全球变量变得更加方便,因为它们需要的工作量更少。这正是人们喜欢使用它们的原因,但请注意,这种懒惰会导致错误的代码:如果使用全局变量,编写代码会更容易,但随后很难理解每个函数的工作原理。理想情况下,函数只需要其参数,然后可以运行并生成结果。在C ++中,通常可以通过查看.hh文件中的声明来查看函数的参数。但是如果函数访问全局变量,我们可以说该函数使用“隐藏”参数,其中“隐藏”意味着它不会在其声明中显示。一旦程序增长到一个非平凡的大小,这实际上会使事情变得更难,因为很难理解变更的后果。例如,如果程序修改了一个全局变量,那么使用该变量的所有函数都会受到影响,但在某些情况下它根本不会显而易见,这将导致难以找到的细微错误。再举一个例子,测试一个函数会变得更加困难:如果你编写一些测试用例,你会发现只要你传递的参数是相同的,只要你运行它们就会得到相同的结果。相反,结果将取决于参数(这是明确的)以及全局变量的值(这是不明显的)。

这就是为什么全局变量不受欢迎的原因:因为它们使编写代码变得容易和快速,但是很难理解并维护它(添加新功能或修复错误)。使用它们不是禁止的,但你应该小心谨慎地使用它们。