我应该使用静态数据成员吗? (C++)
让我们考虑一个 C++ 类。 在执行开始时,我想从 XML 文件中读取一组值并将它们分配给此类的 7 个数据成员。 这些值在整个执行过程中不会改变,并且必须由相关类的所有对象/实例共享。 静态数据成员是实现此行为的最优雅的方法吗? (当然我不考虑全局变量)
Let's consider a C++ class. At the beginning of the execution I want to read a set of values from an XML file and assign them to 7 of the data members of this class. Those values do not change during the whole execution and they have to be shared by all the objects / instances of the class in question. Are static data members the most elegant way to achieve this behavior? (Of course, I do not consider global variables)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
正如其他人提到的,在这种情况下使用静态成员似乎是合适的。 请记住,这并不是万无一失的; 全局数据的一些问题适用于静态成员:
As others have mentioned, the use of static members in this case seems appropriate. Just remember that it is not foolproof; some of the issues with global data apply to static members:
对我来说,听起来静态变量很好用。 您将这些更多地用作固定参数而不是变量,并且这些值需要合法地共享。
Sounds like a good use of static variables to me. You're using these more as fixed parameters than variables, and the values legitimately need to be shared.
静态成员可以在这里工作并且完全可以接受。 另一种选择是对保存这些成员的类使用 单例模式,以确保它们是仅构造/设置一次。
static members would work here and are perfectly acceptable. Another option is to use a singleton pattern for the class that holds these members to ensure that they are constructed/set only once.
这不是一个干净的设计。 静态类成员是全局状态,全局状态不好。
如果这是一个中小型项目并且您对自动测试没有很高的目标,这可能不会给您带来麻烦,但既然您问:有更好的方法。
更简洁的设计是为该类创建一个工厂,并让该工厂在构造该类时将七个变量传递给该类。 那么工厂就有责任确保所有实例共享相同的值。
这样你的类就变得可测试,并且你已经正确地分离了你的关注点。
附言。 不要 使用 单例 要么。
It is not a clean design. Static class members are global state and global state is bad.
It might not cause you trouble if this is a small- to medium-sized project and you do not have high goals for automatic testing, but since you ask: there are better ways.
A cleaner design would be to create a Factory for the class and have the Factory pass your seven variables to the class when it constructs it. It is then the Factory's responsility to ensure that all instances share the same values.
That way your class becomes testable and you have properly separated your concerns.
PS. Don't use singletons either.
听起来像是静态类成员的适当使用。 只是不要忘记它们实际上是具有命名空间和(也许)一些保护的全局变量。 因此,如果您的应用程序有一天可能会发展出单独的“环境”,或者每个环境都需要一组这样的全局变量,那么您就会把自己逼入绝境。
正如 Rob 建议的那样,考虑使用单例,这样以后更容易转换为某种托管环境变量。
sounds like an appropriate use of static class members. just don't forget that they're really global variables with a namespace and (maybe) some protection. therefore, if there's the possibility that your application could someday evolve separate 'environments' or something that would need a set of these globals for each, you'd have painted yourself into a corner.
as suggested by Rob, consider using a singleton, which is easier to turn later into some kind of managed environment variable.
粗体字的句子是这里的关键。 只要该声明成立,就可以使用静态变量。 这将如何执行?
很难。 因此,如果您现在可以使用该陈述,那么就继续吧。 如果您希望未来的开发人员(或您)使用错误的类(例如在程序中途读取另一个 XML 文件),那么请执行 Rasmus Farber 所说的操作。
The sentence in boldface is the kicker here. As long as that statement holds, the use of static variables is OK. How will this be enforced?
It's hard to. So, if for your use right now the statement is always true, go ahead. If you want to be same from some future developer (or you) using your classes wrong (like reading another XML file midway in the program), then do something like what Rasmus Farber says.
是的,静态数据成员就是您所寻找的。 但是您必须注意静态变量的初始化/销毁顺序。 C++ 中没有机制可以确保静态变量在跨翻译单元使用之前已初始化。 为了安全起见,请使用看起来像单例模式的模式,众所周知,它可以解决该问题。 它之所以有效,是因为:
代码:
现在,由 xml_stuff::get_memberN() 返回的对象在任何 xml_stuff 实例的整个生命周期内都有效,因为这些成员中的任何一个都是在任何 xml_stuff 实例之前构造的。 使用普通静态数据成员,您无法确保这一点,因为跨翻译单元的创建顺序在 C++ 中未定义。
Yes, static datamembers are what you look for. But you have to take care for the initialization/destruction order of your static variables. There is no mechanism in C++ to ensure that your static variables are initialized before you use them across translation units. To be safe, use what looks like the singleton pattern and is well known to fix that issue. It works because:
Code:
Now, the objects returned by xml_stuff::get_memberN() are valid the whole lifetime of any xml_stuff instance, because any of those members were constructed before any xml_stuff instance. Using plain static data members, you cannot ensure that, because order of creation across translation units is left undefined in C++.
只要您考虑到可测试性,并且除了读入文件之外,您还有另一种方法来设置静态变量,而且您不依赖于在进程的整个执行时间内保持不变的数据 - 您应该没问题。
我发现在设计代码时考虑编写测试可以帮助您保持代码的良好分解和可重用性。
As long as you think of testability and you have another way to set the static variables besides reading in a file, plus you don't rely on the data benig unchanged for the entire execution time of the process - you should be fine.
I've found that thinking of writing tests when you design your code helps you keep the code well-factored and reusable.