2017-06-01 99 views
0

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

如果你在一个函数中声明了一个变量,那么它的范围不会超出函数的范围。

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

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

+0

全局变量无处不在,无论如何。一个公共变量只能通过你的类的一个实例访问。 – FrenchMajesty

+1

@FrenchMajesty“全局变量在任何地方都可以访问,不管是什么”,只有当它们是外部的,否则它们都被限制在文件范围内。 – George

+0

@George:编译器不知道,所以它必须将任何非静态文件作用域变量视为全局对象。 – MSalters

回答

2

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

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

如果你在一个函数中声明了一个变量,那么它的作用域不会超出该函数的范围。

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

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

不,正如我上面一个公共类变量可以通过成员的任何类,甚至从一些不属于任何类访问说:这正是“公共”的含义。

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

由于CoryKramer在his answer说,一类成员生活的目标内部,对象是相互独立的,因此,如果您创建相同类的10个对象,所有10个都会有自己该变量的副本。 static类成员是一个例外,因为它们由类的所有对象共享,实际上甚至不需要单个对象存在(您是否熟悉Singleton的概念?如果没有静态成员,它将无法工作)。

一个实际的区别:假设您想将文件的名称存储在一个可以从您的所有函数轻松访问的位置。全球都会做。相反,一个类的公共成员要求您先创建该类的对象,然后该对象必须在范围内!如果在main()中创建对象,然后想从名为write_results_to_file()的函数中读取该变量,以便知道要写入哪个文件,则必须注意将该对象传递给该函数,否则该对象将不在尽管公开,范围和公众成员将无法到达。

因此,全局变量更加方便,因为它们需要较少的工作。这正是人们喜欢使用它们的原因,但请注意,这种懒惰带来了糟糕的代码:如果使用全局变量,编写代码更容易,但是很难理解每个函数的工作方式。理想情况下,函数只需要它的参数,然后就可以运行并产生结果。在C++中,通常可以通过查看.hh文件中的声明来查看函数的参数。但是如果函数访问一个全局变量,我们可以说该函数使用了一个“隐藏”参数,其中“隐藏”意味着它不在其声明中显示。一旦程序增长到一个不平凡的大小,这实际上使事情变得更加困难,因为很难理解变化的后果。例如,如果程序修改了一个全局变量,那么所有使用该变量的函数都会受到影响,但在某些情况下,它将不会显而易见,这会导致难以发现的细微错误。再举一个例子,测试一个函数可能会变得更加困难:如果你编写了一些测试用例,只要你传递的参数是相同的,你会期望只要你运行它们,你就会得到相同的结果。相反,结果将取决于参数(这是清楚的),也取决于全局变量的值(这不明显)。这就是为什么全局变量不受欢迎的原因:因为它们使编写代码变得简单快捷,但难以理解并维护它(增加新功能或修复错误)。使用它们不是禁止的,但你应该谨慎而谨慎地做到这一点。

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的实际实例为其访问它的成员变量,我不能做到这一点

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

。而是一个static成员不需要一个实例,并且整个类都有一个共享该成员的单个实例。