C++ public 变量作用域混乱
C++ public variable scope confusion
如果您在 class 中声明了一个 public 变量,那么您可以从任何也是该 class 成员的函数修改该变量。
如果您在函数内声明一个变量,那么它的范围不会超出函数的范围。
那么 public class 变量本质上是一个可以被 class 的任何成员访问和更改的全局变量吗?
如果是这样的话,全局变量和 public 变量有什么区别?
您缺少的更重要的语义是 class 成员变量(除非它是 static
)特定于 那个 class[ 的每个实例=32=]。例如
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
成员不需要实例,整个 class 具有该成员的一个共享实例。
If you declare a public variable in a class, then you can modify that variable from any function that is also a member of that class.
不完全是:这同样适用于私有变量和受保护变量。也就是说,如果 class 有 3 个变量,其中一个是 public
、一个 protected
和一个 private
,则作为该 class 成员的函数不能只修改 public 一个;相反,他们可以修改所有 3 个。作为同一 class 的成员,您将获得最高权限。当尝试从 outside 操作这些变量时,可以看出这 3 个访问修饰符之间的区别 class:public 变量可以从任何地方访问,受保护的变量可以访问来自同一个 class 和从它派生的 classes(如果有的话),私有的只能从同一个 class.
的其他成员访问
If you declare a variable within a function, then its scope doesn't exceed the bounds of the function.
是的,这同样适用于任何块:如果您在 for
循环内声明一个变量,它的作用域就是循环。函数只是一种块。
So is a public class variable essentially a global variable that can be accessed and changed by any member of the class?
不,正如我上面所说的,public class 变量可以被 any class 的成员访问,甚至可以从某些东西访问根本不属于任何 class:这正是 "public".
的含义
If that's the case, what's the difference between a global and public variable?
正如 CoryKramer 在 , a class member lives inside an object, and objects are independent of each other, so if you create 10 objects of the same class, all 10 will have their own copy of that variable. static
class members are an exception, because they are shared by all the objects of the class, and actually don't even need a single object to be present (are you familiar with the concept of Singleton 中所说的那样?如果没有静态成员,它将无法工作。
一个实际的区别:假设您想将文件名存储在一个可以从您的所有函数轻松访问的地方。全球会做。相反,class 的 public 成员要求您首先创建该 class 的对象,然后该对象必须在范围内!如果您在 main()
中创建了对象,然后您想从一个名为 write_results_to_file()
的函数中读取该变量,以便您知道要写入哪个文件,则必须注意将对象传递给该函数, 否则对象将超出范围并且 public 成员将无法访问,尽管 public.
因此全局变量变得更加方便,因为它们需要的工作更少。这正是人们喜欢使用它们的原因,但请注意,这种懒惰会带来糟糕的代码:如果使用全局变量,编写代码会更容易,但理解每个函数的工作原理就更难了。理想情况下,一个函数只需要它的参数,然后它可以是 运行 并产生一个结果。在 C++ 中,通常您可以通过查看函数在 .hh 文件中的声明来查看函数的参数。但是如果函数访问一个全局变量,我们可以说函数使用了一个 "hidden" 参数,其中 "hidden" 意味着它没有显示在它的声明中。一旦程序增长到非常大的规模,这实际上会使事情变得更难,因为很难理解变化的后果。例如,如果程序修改了一个全局变量,那么所有使用该变量的函数都会受到影响,但在某些情况下根本不会很明显,这会导致难以发现的细微错误。再举一个例子,测试一个函数会变得更加困难:如果你写了一些测试用例,你会希望每当你 运行 它们时你得到相同的结果,只要你传递的参数是相同的。相反,结果将取决于参数(很明显)以及全局变量的值(不明显)。
这就是为什么全局变量不受欢迎的原因:因为它们使编写代码变得容易和快速,但理解和维护它(添加新功能或修复错误)却困难且缓慢。不禁止使用它们,但您应该小心谨慎地使用它们。
如果您在 class 中声明了一个 public 变量,那么您可以从任何也是该 class 成员的函数修改该变量。
如果您在函数内声明一个变量,那么它的范围不会超出函数的范围。
那么 public class 变量本质上是一个可以被 class 的任何成员访问和更改的全局变量吗?
如果是这样的话,全局变量和 public 变量有什么区别?
您缺少的更重要的语义是 class 成员变量(除非它是 static
)特定于 那个 class[ 的每个实例=32=]。例如
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
成员不需要实例,整个 class 具有该成员的一个共享实例。
If you declare a public variable in a class, then you can modify that variable from any function that is also a member of that class.
不完全是:这同样适用于私有变量和受保护变量。也就是说,如果 class 有 3 个变量,其中一个是 public
、一个 protected
和一个 private
,则作为该 class 成员的函数不能只修改 public 一个;相反,他们可以修改所有 3 个。作为同一 class 的成员,您将获得最高权限。当尝试从 outside 操作这些变量时,可以看出这 3 个访问修饰符之间的区别 class:public 变量可以从任何地方访问,受保护的变量可以访问来自同一个 class 和从它派生的 classes(如果有的话),私有的只能从同一个 class.
If you declare a variable within a function, then its scope doesn't exceed the bounds of the function.
是的,这同样适用于任何块:如果您在 for
循环内声明一个变量,它的作用域就是循环。函数只是一种块。
So is a public class variable essentially a global variable that can be accessed and changed by any member of the class?
不,正如我上面所说的,public class 变量可以被 any class 的成员访问,甚至可以从某些东西访问根本不属于任何 class:这正是 "public".
的含义If that's the case, what's the difference between a global and public variable?
正如 CoryKramer 在 static
class members are an exception, because they are shared by all the objects of the class, and actually don't even need a single object to be present (are you familiar with the concept of Singleton 中所说的那样?如果没有静态成员,它将无法工作。
一个实际的区别:假设您想将文件名存储在一个可以从您的所有函数轻松访问的地方。全球会做。相反,class 的 public 成员要求您首先创建该 class 的对象,然后该对象必须在范围内!如果您在 main()
中创建了对象,然后您想从一个名为 write_results_to_file()
的函数中读取该变量,以便您知道要写入哪个文件,则必须注意将对象传递给该函数, 否则对象将超出范围并且 public 成员将无法访问,尽管 public.
因此全局变量变得更加方便,因为它们需要的工作更少。这正是人们喜欢使用它们的原因,但请注意,这种懒惰会带来糟糕的代码:如果使用全局变量,编写代码会更容易,但理解每个函数的工作原理就更难了。理想情况下,一个函数只需要它的参数,然后它可以是 运行 并产生一个结果。在 C++ 中,通常您可以通过查看函数在 .hh 文件中的声明来查看函数的参数。但是如果函数访问一个全局变量,我们可以说函数使用了一个 "hidden" 参数,其中 "hidden" 意味着它没有显示在它的声明中。一旦程序增长到非常大的规模,这实际上会使事情变得更难,因为很难理解变化的后果。例如,如果程序修改了一个全局变量,那么所有使用该变量的函数都会受到影响,但在某些情况下根本不会很明显,这会导致难以发现的细微错误。再举一个例子,测试一个函数会变得更加困难:如果你写了一些测试用例,你会希望每当你 运行 它们时你得到相同的结果,只要你传递的参数是相同的。相反,结果将取决于参数(很明显)以及全局变量的值(不明显)。
这就是为什么全局变量不受欢迎的原因:因为它们使编写代码变得容易和快速,但理解和维护它(添加新功能或修复错误)却困难且缓慢。不禁止使用它们,但您应该小心谨慎地使用它们。