1

我们有一个 Java 消息传递 API,我们正在将其翻译成 C++。消息通常具有简单的数据类型,如字符串、整数、双精度等。构造消息时,我们将所有成员变量初始化为 API 识别为“空”值的默认值(即从不设置为任何值),例如Integer.MAX_VALUE对于 int 类型。任何被视为 null 的字段都不会被序列化和发送。

在 Java 中,字符串会自动初始化为,null因此很容易区分为 null 的字符串字段与为空字符串的字符串(这是在消息中发送的合法值)。

我不确定在 C++ 中处理此问题的最佳方法,因为字符串会自动初始化为空字符串,而空字符串是通过 API 发送的合法值。我们可以将字符串默认为某个控制字符(这在我们的 API 中不是合法值),但我想知道是否有更传统或更好的方法来做到这一点。

我们都是 C++ 新手,所以我们可能忽略了一些明显的方法。

4

2 回答 2

5

推荐的方法是使对象在具有有效值之前不存在。如果带有空字符串的消息无效,为什么要允许呢?

在 Java 中你无法避免它,因为字符串总是可以为空的。但是 C++ 为您提供了创建一个类的工具,该类保证始终包含一个字符串。

听起来这就是你想要的。

对于您所要求的,最好的方法实际上是在类中构建该类的对象始终具有字符串 set的不变量。不要在构造函数中将所有对象设置为某个默认值,而是定义构造函数以获取实际参数并将成员设置为有效值

但是,如果您想指定一个“可选”值,有几种广泛的方法:

  • 要么使用指针(最好是智能指针)。指向字符串的指针可以为空,也可以指向有效的字符串(同样,它可能为空,也可能不为空)
  • 或者,使用类似boost::optionalBoost 库中的东西。这是一个聪明的小实用程序模板,可以让您定义可选值(对象可能包含字符串,也可能为空)
  • 或者您可以简单地添加一个bool标志(类似has_string,如果未设置,则表示未设置任何字符串,并且应忽略字符串值)。

就个人而言,我更喜欢最后两种方法,但是这三种方法都相当常用,并且可以正常工作。但最好的方法是设计类,以便编译器可以保证它始终有效。如果您不想要带有空字符串的消息,让编译器确保消息永远不会有空字符串。

于 2013-06-18T18:54:30.797 回答
2

要复制 Java “事物可以有值,也可以缺少值”,可能最通用的方式是boost::optional<T>存储std::optional<T>.

如果你想读取它们的值,你必须投入一些,*并且要小心,因为它的默认转换为“我是否已初始化?”,而不是存储的那个。但是在写入它时几乎可以做到你想要它做的事情,它只是从中读取可以在上下文中做意想不到的事情。->optional<bool>boolbooloperator=bool

要判断 anoptional<T>是否已初始化,只需在bool上下文中评估它,就像您可能使用指针一样。要在确认已初始化后提取其值,请使用一元运算*符。

boost是一个相对高质量的库,在 5 到 10 年内代码从它迁移到 C++ 标准的速度很高。它确实包含一些可怕的部分(比如 phoenix!),一般来说,您应该确保您使用的任何组件都不在 C++ 标准库中(已经迁移到那里)。 boost::optional特别是它们的仅标头库的一部分,这些库更易于使用(因为您不必构建boost即可使用它们)。

于 2013-06-18T19:13:21.660 回答