没有指针 C++ 字符串如何表达字符串是 nullptr?

without pointer C++ string how to expression string is nullptr?

提问人:Tom 提问时间:9/27/2022 最后编辑:wohlstadTom 更新时间:9/28/2022 访问量:169

问:

在C++字符串上可以表达两种情况:

1. string flag;                     /* empty string */
1. string flag = "Other content";   /* other string */

在Java上String可以表达三种情况:

1. String flag = NULL;              /* NULL */
2. String flag = "";                /* empty string */
2. String flag = "Other content";   /* other string */

在 C++ 上,我们可以将字符串表示为 NULL () 吗?如果没有,请使用指针。nullptr

我的场景: 我从mysql中获取了字符串数据,mysql表达式的方式与Java的字符串相同,// 。NULLemptyother

我的数据模型用于 Mysql 和 nlohmann Json。

java c++ null

评论

3赞 Nathan Pierson 9/27/2022
如果你真的需要区分“没有字符串”和“空字符串”,你可以使用 std::optional
1赞 Abel 9/27/2022
在 java 中,一切都是一个对象,而对象又本质上指向代表该对象的内存。您可以使用指向字符串的 ref 计数指针来获得相同的计算结果。您还可以创建一个包含多个字符的字符串,其中第一个字符为 null...
0赞 Tom 9/27/2022
谢谢,std::optional 是很好的指针是 whell ,但是使用这些方式,我必须与 nlohmann Json 自我兼容。也许这是我唯一的办法。

答:

1赞 wohlstad 9/27/2022 #1

下面的答案是相当理论化的。
在实践中,通常不需要区分空字符串和空字符串,按原样使用是最佳解决方案。如果你只需要在你的 C++ 字符串中添加“nullabilty”,你可以按照注释和其他答案中提到的使用。
std::stringstd::optional


话虽如此:

在 Java 中,a 是一种引用类型,这意味着变量实际上保存对对象的引用(并且引用可以为 null)。一个对象可以有多个引用,当这个数字变为零时,可以自动销毁该对象。StringflagString

如果你想在 C++ 中实现整体相似的行为,你可以使用 std::shared_ptr 持有 :std::string

#include <memory>
#include <string>
//...
std::shared_ptr<std::string> s1 = nullptr;      // null string
std::shared_ptr<std::string> s2 = std::make_shared<std::string>("");    // empty string
std::shared_ptr<std::string> s3 = std::make_shared<std::string>("abs"); // non empty string

评论

0赞 Fantastic Mr Fox 9/27/2022
但你不应该对吗?只需使用值语义
1赞 wohlstad 9/27/2022
@FantasticMrFox 添加了关于是否真的需要此构造的前言。
2赞 Fantastic Mr Fox 9/27/2022 #2

因此,您可以使用以下方式来表达这一点:std::optional

std::optional<std::string> null_string = std::nullopt; // this is the "null" state

if (optional_string) { /// Can be used like a null or bool type

std::optional<std::string> empty_string = ""; // This is the empty string
std::optional<std::string> other_string = "Other content"; // The full string

请注意,要使用字符串接口,您需要使用 或 获取字符串的值:.value()operator*

void print_string(const std::string& s);

print_string(*other_string);

这要求您在调用之前检查字符串是否确实有效,否则您将调用未定义的行为。

0赞 Tom 9/28/2022 #3

在 C++ 上,我们可以将字符串表示为 NULL (nullptr) 吗?

不,你不能.想要将字符串表达为 nullptr 需要字符串指针

在 C++ 上,我们可以将字符串表示为 NULL (nullptr) 吗?如果没有,请使用指针。

也许 std::optional 是答案。

我的数据模型用于 Mysql 和 nlohmann Json。

  1. 假设选择std::optional<string> flag

  2. 对于MySQL,可以表达式字符串NULL ,flag = nullopt

  3. 对于 nlohmann Json ,您必须兼容std::optional

    namespace nlohmann {
      /* https://github.com/nlohmann/json#how-do-i-convert-third-party-types */
      template <typename T>
      struct adl_serializer<std::optional<T>> {
          static void to_json(json& j, const std::optional<T>& opt) {
            if(opt.has_value()) {
                // this will call adl_serializer<T>::to_json which will
                // find the free function to_json in T's namespace!
                j = opt.value();
            } else {
                j = nullptr;
            }
          }
    
          static void from_json(const json& j, std::optional<T>& opt) {
              if (j.is_null()) {
                opt = std::nullopt;
              } else {
                opt = j.get<T>(); // same as above, but with
                                  // adl_serializer<T>::from_json
              }
          }
      };
    }
    

其他事项

  1. 复制表格@wohlstadIn Java a String is a reference type, meaning variables like flag actually hold a reference to the String object (and the reference can be null).

我的参考资料 :

  1. https://github.com/nlohmann/json/issues/1749
  2. https://www.kdab.com/jsonify-with-nlohmann-json/