C++相当于Java静态最终字符串

C++ equivalent of Java static final String

本文关键字:字符串 静态 相当于 Java C++      更新时间:2023-10-16

我经常需要定义与类关联的字符串常量。 例如 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"; }
}

这也提供了一些封装和灵活性。但是,仅使用函数来定义常量似乎有点奇怪。

所以我的问题是,这种解决方案是否有重大缺点,如果是,还有什么更好的选择?

在 c++03 中,最好的选择是按照你正在使用的方式使用函数,这很尴尬。唯一的问题是,当您可以免费归还const char* const时,您为什么要归还std::string并支付其建筑价格。

如果出于某种原因,您真的必须const std::string(再次,它违背了我的整个经验,因此您可能需要重新考虑)以下代码在效率方面效果最好(您当前的版本在每次调用时都调用std::string构造函数!

class Example {
public:
    static const std::string& key() {
       static const std::string the_key = "That's my key!";
       return the_key;
    }
}

在 c++11 中,您有几个选项,其中我认为最好的constexpr

class Example {
public:
    static constexpr const char* const KEY = "TheKey";
}

另一种选择是就地初始化 const 字符串,但为什么要为此付出代价呢?

class Example {
public:
    static const std::string KEY = "TheKey";
};

而在 Java 中,类及其静态成员与类一起加载——这意味着类作为一个单元或作为 JAR 的一部分是可替换的——C++它不会那样做。如果你把东西放在标题中,你会付出无法替换它们的代价,直到你重新编译包含它们的所有内容。

这就是为什么惯用的——也是最有益的——方法是在标头中声明它们,并在它所属的地方提供实现,在翻译单元中,它可以链接到任何其他二进制文件。所以考虑重新调整你的观点(我从 C# 转到 C++ 所以我不止一次遇到这种情况)。

但是你根本不需要走字符串的道路。您可以创建枚举,这是一种更优雅且类型安全的方式来实现此目的。使用枚举(特别是枚举类),您不能只传入错误的字符串。您必须传入一组有效值之一。

例如,您可以执行以下操作:

class Example {
public:
    enum class Attributes {
        One,
        Two,
        // ...
    };
}

然后,当它很重要时,当你对什么是什么有本地知识时,你可以将枚举值映射到实际字符串或实际实现所需的内容。

您可以定义类的构造函数,以便每次使用该类时,构造函数都会自动将值"属性分配给字符串"

class Example {
   public:
      static const std::string KEY;
      Example()
      {
          KEY="Attribute";
      }
};