说我有这种方法:

bool match( /* some optional parameter */ );

它将执行一些字符串模式匹配,我想允许给它一个可选参数,该方法仅在方法Match返回match()时填充一个已知类型(true)的实例,这样可能吗?

在PHP中,我可以这样做:
public function match( Match &$match = null ) {
  if( someMatchingRoutineMatched() ) {
    $match = new Match();
    return true;
  }

  return false; // $match will stay null
}

然后这样称呼它:
// $test is some instance of the class that implements match()
// I don't have to declare $m up front, since it will be filled by reference
if( $test->match( $m ) ) {
  // $m would be filled with an instance of Match
}
else {
  // $m would be null
}

在c++中是否可能有类似的东西?

我有点理解它可以与以下内容一起使用
bool match( Match*& match ) {
  if( /* something matches */ ) {
    match = new Match;
    return true;
  }

  return false;
}

...然后像这样调用它:
Match* m = nullptr; // I wish I wouldn't have to declare this upfront as a nullptr
if( test.match( m ) ) {
  // a match occured, so m should no longer be a null pointer
  // but let's just make sure
  if( m != nullptr ) {
    // do something useful with m and afterwards delete it
    delete m;
  }
}

...但是,这一切都有点麻烦。此外,我似乎不允许将参数设为可选,例如:
bool match( Match*& match = nullptr );

...因为我相信引用不允许为空,对吗?

希望您能看到我正在努力实现的目标,并且如果可以的话,也可以给我一些如何实现目标的见识。

最佳答案



不允许使用Match*& match = nullptr,因为对非const的引用无法绑定(bind)到临时对象,并且在此处传递nullptr会创建一个临时的Match*

您可以返回指针,而不是传递对非const的引用:

Match* match() {
  if( /* something matches */ ) {
    return new Match;
  }

  return nullptr;
}

现在,nullptr返回值表示没有匹配项,而非nullptr表示已找到匹配项:
if( Match* m = test.match() ) { // nullptr means false, non-nullptr means true
  if( m != nullptr ) { // always true here
    // do something useful with m and afterwards delete it
    delete m;
  }
}

或者您可以使用@DanMašek提到的重载:
bool match() {
  Match* m = nullptr;
  bool result = match(m);
  delete m; // deleting a nullptr is a no-op
  return result;
}

最后但并非最不重要的一点是,强制使用unique_ptr -over-raw-owning-pointer,因此您不必担心delete,并且无需阅读match文档就可以清楚地知道返回的指针是拥有还是不拥有:
unique_ptr<Match> match() {
  if( /* something matches */ ) {
    return make_unique<Match>( /* constructor arguments */ );
  }

  return nullptr;
}

if( auto m = test.match() ) { // m deduced to be of type unique_ptr<Match>
  if( m != nullptr ) { // always true here
    // do something useful with m and afterwards delete it
    // no need to delete explicitly
  }
}

10-02 00:50
查看更多