我经常需要定义与类关联的字符串常量。示例包括XML属性,默认文件名等等。
在Java中,我只想定义类似
的内容public static final String KEY = "attribute";
在类或接口中。
在C ++中,以下内容无法编译:
class Example {
public:
static const std::string KEY = "attribute";
}
相反,我必须写:
class Example {
public:
static const std::string KEY;
}
const std::string Example::KEY = "attribute";
这是我绝对想要避免的,因为它的冗余和冗长。
我到目前为止找到的最佳解决方案是使用函数:
class Example {
public:
static std::string KEY() const { return "attribute"; }
}
这也提供了一些封装和灵活性。然而,使用函数来定义常量似乎有点奇怪。
所以我的问题是,这个解决方案是否存在重大缺陷,如果是,那么更好的替代方案是什么?
答案 0 :(得分:2)
在c ++ 03中,你最好的选择是按照你使用的方式使用一个函数,这很尴尬。唯一的问题是,当您可以免费返回std::string
时,为什么要返回const char* const
并支付建筑价格。
如果由于某种原因,你真的必须const std::string
(再次,它会违背我的整体经验,所以你可能想重新考虑)以下代码在效率方面最有效(你当前的版本调用{每次调用{1}}构造函数!):
std::string
在c ++ 11中,您有几个选项,其中我发现最好的class Example {
public:
static const std::string& key() {
static const std::string the_key = "That's my key!";
return the_key;
}
}
:
constexpr
另一个选项是你的const字符串的就地初始化,但为什么付出它的代价呢?
class Example {
public:
static constexpr const char* const KEY = "TheKey";
}
答案 1 :(得分:-1)
对于Java,类及其静态成员与类一起加载 - 这意味着作为一个单元或作为JAR的一部分的类是可替换的 - 在C ++中它不会那样。如果你把东西放在标题中,那么在重新编译包含它们的所有内容之前,你需要付出代价才能替换它们的代价。
这就是为什么惯用语和最有益的方式是在标题中声明它们并在翻译单元中提供它所属的实现,可以链接到任何其他二进制文件。所以考虑重新调整你的观点(我从C#转移到C ++,所以我不止一次地发生这种情况)。
但你根本不需要采用字符串的方式。您可以创建枚举,这是一种更优雅,更安全的方式来实现这一点。使用枚举(特别是枚举类),您不能只传入错误的字符串。您必须传入一组有效值。
作为一个例子,你可以这样做:
class Example {
public:
enum class Attributes {
One,
Two,
// ...
};
}
然后,当它重要时,当你对当时的内容有所了解时,你可以将枚举值映射到实际字符串或实际实现所需的内容。
答案 2 :(得分:-4)
您可以定义类的构造函数,以便每次使用该类时,构造函数都会自动将值"属性赋值给字符串"
class Example {
public:
static const std::string KEY;
Example()
{
KEY="Attribute";
}
};