常量字符串应该是静态数据成员,还是应该位于未命名的命名空间中?
我需要定义一些仅由一个类使用的常量字符串。看起来我有三个选择:
将字符串直接嵌入到使用它们的位置。
将它们定义为类的私有静态常量成员:
//啊 A类{ 私人的: 静态常量 std::string f1; 静态常量 std::string f2; 静态常量 std::string f3; };
//A.cpp const std::string f1 = "文件名1"; const std::string f2 = "文件名2"; const std::string f3 = "文件名3"; //该文件中使用字符串
在 cpp 文件中的未命名命名空间中定义它们:
//A.cpp 命名空间{ const std::string f1 = "文件名1"; const std::string f2 = "文件名2"; const std::string f3 = "文件名3"; } //此文件中使用字符串
给定这些选项,您会推荐哪一个,为什么?
I need to define some constant strings that will be used only by one class. It looks like I have three options:
Embed the strings directly into locations where they are used.
Define them as private static constant members of the class:
//A.h class A { private: static const std::string f1; static const std::string f2; static const std::string f3; };
//A.cpp const std::string f1 = "filename1"; const std::string f2 = "filename2"; const std::string f3 = "filename3"; //strings are used in this file
Define them in an unnamed namespace in the cpp file:
//A.cpp namespace { const std::string f1 = "filename1"; const std::string f2 = "filename2"; const std::string f3 = "filename3"; } //strings are used in this file
Given these options, which one would you recommend and why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
我将它们放置在 CPP 文件中的匿名命名空间中。它使它们对于实现而言是私有的,同时使其对作为实现一部分的非成员函数(例如
operator<<
)可见。I'd place them in anonymous namespace in the CPP file. It makes them private to the implementation and at the same moment makes it visible to the non-member functions that are part of implementation (such as
operator<<
).如果它们仅在单个文件中使用,则无需通过将它们包含在头文件中来将它们公开给外界。
如果它们被使用并且将始终仅在一个地方使用,那么确实没有理由不在需要使用它们的地方将它们写为文字。
如果它们在 cpp 中的多个位置使用,我会选择匿名命名空间。
您没有提到的另一个选项是将它们定义为 cpp 内的静态变量。这在某种程度上相当于匿名名称空间选项,并且比 C++ 更像 C。
If they are used only in a single file then there is no need to expose them to the outside world by including them in the header file.
If they are used and will always be used only in a single place then there's really no reason not to just write them as literals where they need to be used.
If they are used in multiple places in the cpp, I would go for the anonymous namespace.
Another option which you don't mention is to define them as static variables inside the cpp. this is somewhat equivalent to the anonymous namespace option and more C-like than C++.
类的静态成员。
如果它们被一个类在多个地方使用,那么通常更容易保持事物的组织性 - 并且稍后找到定义所有内容的位置 - 如果您将它们定义在使用它们的类中。就地定义它们会使它们难以定位和稍后修改。我会选择特定的类而不是匿名命名空间,以获得更清晰的类定义和使用。
Static members of the class.
If they are used in multiple places by the one class, it's usually easier to keep things organized - and to later find where you defined everything - if you keep them defined in the class that uses them. Defining them in-place makes them hard to locate and later modify. And I'd opt for the specific class over the anonymous namespace for cleaner class definition and use.
如果字符串要让类的用户看到,请将它们放入类中。否则,将它们隐藏在实现文件的未命名命名空间中。
If the strings are meant to be seen by users of the class, put them into the class. Otherwise, hide them in the implementation file's unnamed namespace.
如果仅在类的 .cpp 文件中使用,则无需使用任何类型的命名空间,简单地说:
过度使用命名空间似乎是新事物 - 我个人看不出吸引力。
If only used in the class's .cpp file, there is no need to use a namespace of any sort, simply say:
Overuse of namespaces seems to be the new thing - I can't personally see the attraction .
在这三个选项中,您真正应该避免的唯一一个是#1。不要在代码中使用魔法cookie。通过将常量放入命名空间或类中,您可以更轻松地在将来扩展和维护代码。
如果你的常量本质上是全局的,那么在 2 到 3 之间就没什么关系了。重要的是你选择了一个并坚持下去。但是,如果您有适用于特定类的常量,那么它们应该是该类的一部分。
就我个人而言,我会使用命名空间来处理大多数事情。
Of the three options, the only one you should really avoid is #1. Don't use magic cookies in your code. By putting the constants either in a namespace or a class, you make it easier to extend and maintain your code in the future.
If your constants are global in nature, then between 2 and 3, it matters little. What matters is that you choose one and stick with it. But if you have constants that apply to a particular class, then they should be a part of that class.
Personally, I'd use a namespace for most things.
我认为真正的问题是:字符串真的只在实现类时在内部使用,还是在其他地方使用。
为了真正挑剔,我会尽力保持类的接口尽可能干净,因此文件名字符串不应引起“外部”世界的任何兴趣。我只会将它们隐藏在 .cpp 文件内部。在这种情况下,我认为我不会打扰命名空间,而只是保持“静态”(即 .cpp 文件内部)。
I think the real issue is: Are the strings really only used internally when implementing the class, or are they used elsewhere.
To be really nit-picky, I would try to keep the interface of the class as clean as possible, so if the filename-strings should not be of any interest to the "outside" world. I would hide them internally in the .cpp-file only. And in that case I don't think I would bother with the namespace, but just keep things "static" (i.e. internal to the .cpp-file).
不管你怎么做,需要注意一件事:我不建议使用静态 std::string 对象,而是使用静态 char*。其原因是初始化顺序的潜在问题。假设您有一个类的静态实例,其构造函数引用字符串
A::f1
。无法保证A::f1
已经构建完毕,并且您会遇到崩溃,或者更糟糕的是,没有崩溃但有虚假数据。追踪初始化顺序错误可能非常令人讨厌,并且在一个项目中一切看起来都很好,但随后您可能会使用相同的库构建另一个项目,并且链接顺序中的细微差别将导致此错误神秘地出现。
However you do it, one thing to be careful of: I wouldn't recommend using static std::string objects, instead use static char*. The reason for this is due to potential problems with order of initialisation. Say you have a static instance of a class whose constructor references the string
A::f1
. There is no guarantee thatA::f1
has been constructed yet, and you'll get a crash, or worse, no crash but bogus data.Tracking down order-of-initialisation bugs can be pretty nasty, and everything may look fine in one project, but then you might build another project using the same libraries, and the subtle differences in the link order will cause this bug to mysteriously appear.
只需在实现文件中的文件范围内包含 const 字符串,匿名名称空间就不需要将它们的使用限制为仅该类。
C++ 003 标准 C.1.2 条款3:基本概念
注意:匿名命名空间确实有助于减少命名冲突。
Just have the const strings at file scope in the implementation file, the anonymous namespace is not necessary to restrict their use to that class only.
C++ 003 Standard C.1.2 Clause 3: basic concepts
Note: The anonymous namespace does help reduce naming conflicts.