【问题标题】:Java-like null for string and ofstream arguments in c++c++ 中字符串和 ofstream 参数的类似 Java 的 null
【发布时间】:2013-04-05 13:35:03
【问题描述】:

我有一些 Java 代码(构造函数)

RecursiveDescentParser
(
  std::string inputStream, 
  bool fileService, 
  std::string filePathName, 
  std::ofstream writer
)
{
  input_ = inputStream;
  tokenizer_ = new Tokenizer(inputStream);
  if (fileService == true){
      error = new ErrorHandling(fileService, std::move(writer));
  }
  else{
      error = new ErrorHandling(fileService, std::ofstream());
  }     
  compiled_ = "";
}

Tokenizer *tokenizer_;

std::string input_, compiled_;

我想在 C++ 中模拟一个调用

RecursiveDescentParser *parser = new RecursiveDescentParser
(
  stream, 
  false, 
  null, 
  null
);

如果我使用指针参数

std::string *str; std::ofstream *out

我可以传入nullptr,但如果我选择不使用指针参数,我就不能传递null。 我可以做些什么来模拟将 null 传递给 std::string 和 std::ofstream?

【问题讨论】:

  • 为什么不使用默认参数并默认初始化它们?
  • 您可以使用boost::optional 或另一种机制来告诉您的函数该参数未传递。
  • @jotep 默认将它们初始化为什么?
  • @MikeSeymour 空字符串和标准输出
  • @andre 请仔细阅读问题。 OP 说如果我使用指针,我可以传递 NULL,但如果我不这样做,我该怎么办?

标签: c++ null arguments


【解决方案1】:

正如您所说,指针是一种选择;但是会产生复杂性,因为您需要单独管理对象或使用智能指针。共享指针是一种可能性,并且提供与 Java 的对象引用非常相似的语义(仅使用引用计数而不是垃圾收集)。

对于可空对象类型,您可以使用Boost.Optional,或实现您自己的可空包装类。有人说optional 将被包含在未来的标准库中;但就目前而言,您需要 Boost。

另外,提供第二个完全不接受这些参数的构造函数可能更有意义。

【讨论】:

  • 我阅读了Boost.Optional 并想要一个清晰的具体示例来说明如何为参数实现它。
  • @Mushy:参数是boost::optional<std::string>,你可以传递一个字符串或boost::none
  • Boost.Optional 的#include 路径是什么?
  • @Mushy: boost/optional.hpp
  • 我在 boost::optional<:ofstream> 上遇到了与无复制/无分配有关的问题。例如,如果我指定 const boost::optional<:ofstream> &writer 作为参数,我该怎么做?
【解决方案2】:

这就是我将如何改变你的用法:

RecursiveDescentParser
(
  std::string inputStream, 
  bool fileService = false, 
  std::string filePathName = "", 
  std::ofstream* writer = NULL
)

RecursiveDescentParser *parser = new RecursiveDescentParser(stream);

【讨论】:

    【解决方案3】:

    你有两个选择——要么创建一个代表可选值的包装类,要么使用指针。我强烈推荐第一个选项。

    此外,在某些情况下,您可能会认为空字符串等同于未设置值。

    【讨论】:

      【解决方案4】:

      遗憾的是,C++ 中的字符串是对象,与 java 不同的是,C++ 对象不能为空。

      据我了解,您正在为 RecursiveDescentParser 创建一个构造函数。 构造函数的工作是初始化对象。

      如果允许构造函数接受一个指针,它可以接受一个空路径字符串,那么它就会被创建一个空路径字符串,因为构造函数的工作是初始化所有字段,而空字段没有被初始化,这不是一个好的解决方案。

      我的建议是将构造函数设为私有,但创建一个公共方法,该方法可以接受构造函数将接受的参数,但也可以是指向字符串而不是对象的指针。如果路径字符串指针为空,则抛出异常,或返回错误对象。如果路径字符串有效,则根据路径字符串指针指向的字符串的引用创建一个新的解析器,并返回这个引用。

      虽然,我可以完全离开,但这只是一个建议,我欢迎所有关于为什么这不起作用的建设性批评。

      【讨论】:

      • C++ strings 不再是引用,ints 是引用。 C++ std::string 充满了值类型。
      • 字符串不是引用,它们是对象。但你说得对,对象不能为空。
      • 已修改。无需投票,我愿意纠正所有不准确之处,我只是提出解决方案。
      • 您可能还想更改或删除有关“空字段”的段落,因为这根本没有意义。
      • 我对其进行了修改以使其更有意义。
      猜你喜欢
      • 2018-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-07
      • 1970-01-01
      • 2013-01-26
      • 2021-09-22
      相关资源
      最近更新 更多