0

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

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

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

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

4

2 回答 2

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

因为我需要一个实际的 a实例Foo来访问它的成员变量。相反,static成员不需要实例,并且整个类具有该成员的单个实例,该实例是共享的。

于 2017-06-01T21:46:31.440 回答
3

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

Not exactly: the same also applies to private and protected variables. That is, if a class has 3 variables, one of them being public, one protected and one private, the functions that are members of that class can't only modify the public one; on the contrary, they can modify all 3. Being a member of the same class gives you the highest permissions. The difference between these 3 access modifiers can be seen when trying to manipulate those variables from outside that class: public variables are reachable from anywhere, protected variables are reachable from the same class and from classes derived from it (if there are any), and private ones are reachable only from other members of the same class.

If you declare a variable within a function, then its scope doesn't exceed the bounds of the function.

Yes, and the same actually applies to any block: if you declare a variable inside a for loop, its scope will be the loop. Functions are just one kind of block.

So is a public class variable essentially a global variable that can be accessed and changed by any member of the class?

No, as I said above a public class variable can be accessed by members of any class, and even from something that doesn't belong to any class at all: that's exactly the meaning of "public".

If that's the case, what's the difference between a global and public variable?

As CoryKramer said in his answer, 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? Without static members it wouldn't work).

A practical difference: let's say you want to store the name of a file in a place that is easily accessible from all your functions. A global will do. A public member of a class, instead, requires you to create an object of that class first, and then that object must be in scope! If you create the object inside main() and then you want to read that variable from a function called write_results_to_file(), so that you know which file to write to, you must take care about passing the object to that function, otherwise the object will be out of scope and the public member will be unreachable, despite being public.

So global variable come more handy, as they require less work. This is exactly the reason that people like using them, but please note that this kind of laziness brings to bad code: if you use global variables, writing the code is easier, but then it's harder to understand how each function works. Ideally a function only requires its arguments, and then it can be run and produce a result. In C++ usually you can see the arguments of a function by looking at its declaration in the .hh file. But if the function accesses a global variable, we could say that the function uses a "hidden" argument, where "hidden" means that it isn't displayed in its declaration. As soon as a program grows to a non-trivial size, this actually makes things harder, because it's difficult to understand the consequences of changes. For example, if the program modifies a global variable, all the functions that use that variable will be affected, but in some cases it won't be obvious at all, and this will lead to subtle bugs that are hard to find. To make another example, testing a function can become a lot harder: if you write some test cases, you would expect that whenever you run them you get the same result, as long as the arguments you pass are the same. Instead, the result will depend on the arguments (which is clear) and also on the value of the global variables (which isn't obvious).

That's why global variables are frowned upon: because they make it easy and fast to write code, but hard and slow to understand it and maintain it (to add new features or to fix bugs). Using them isn't forbidden, but you should do it carefully and sparingly.

于 2017-06-01T23:00:15.233 回答