如果未找到搜索结果,则返回"NULL"对象

adu*_*ric 91 c++ return-value sentinel

我对C++很陌生,所以在我学习的时候,我倾向于设计很多Java主义.无论如何,在Java中,如果我的类具有"搜索"方法,该方法T将从Collection< T >匹配特定参数的对象返回一个对象,我将返回该对象,如果在集合中找不到该对象,我将返回null.然后在我的调用函数中,我会检查if(tResult != null) { ... }

在C++中,我发现null如果对象不存在,我就无法返回值.我只想返回一个类型为T的'指示符',它通知调用函数没有找到任何对象.我不想抛出异常,因为它并不是一个特例.

这就是我的代码现在的样子:

class Node {
    Attr& getAttribute(const string& attribute_name) const {
       //search collection
       //if found at i
            return attributes[i];
       //if not found
            return NULL; // what should this be?
    }

private:
    vector<Attr> attributes;
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能改变它以便我能给出那种标记?

Jes*_*der 66

在C++中,引用不能为null.如果要在找不到任何内容时可选地返回null,则需要返回指针,而不是引用:

Attr *getAttribute(const string& attribute_name) const {
   //search collection
   //if found at i
        return &attributes[i];
   //if not found
        return nullptr;
}
Run Code Online (Sandbox Code Playgroud)

否则,如果您坚持通过引用返回,那么如果找不到该属性,则应该抛出异常.

(顺便说一下,我有点担心你的方法正在运行const并返回非const属性.出于哲学原因,我建议返回const Attr *.如果你也想修改这个属性,你可以用非const方法重载也返回非const属性.)

  • 好奇,我们现在应该为c ++ 11返回`nullptr`而不是`NULL`吗? (7认同)
  • @aduric:是的.参考意味着结果必须存在.指针暗示结果可能不存在. (6认同)
  • 谢谢.顺便说一下,这是设计这样一个例程的公认方式吗? (2认同)

Kaz*_*gon 55

这里有几个可能的答案.您想要返回可能存在的内容.以下是一些选项,从最不喜欢的到最喜欢的:

  • 通过引用返回,并且异常无法找到信号.

    Attr& getAttribute(const string& attribute_name) const 
    {
       //search collection
       //if found at i
            return attributes[i];
       //if not found
            throw no_such_attribute_error;
    }
    Run Code Online (Sandbox Code Playgroud)

很可能找不到属性是执行的正常部分,因此不是非常特殊.对此的处理将是嘈杂的.无法返回空值,因为它具有空引用的未定义行为.

  • 按指针返回

    Attr* getAttribute(const string& attribute_name) const 
    {
       //search collection
       //if found at i
            return &attributes[i];
       //if not found
            return nullptr;
    }
    Run Code Online (Sandbox Code Playgroud)

很容易忘记检查getAttribute的结果是否是非NULL指针,并且是一个容易出错的bug.

boost :: optional表示这里发生了什么,并且有简单的方法来检查是否找到了这样的属性.


旁注:std :: optional最近被投票到C++ 17中,因此在不久的将来这将是一个"标准"的东西.

  • @MatthieuM.开销aduric可能指的不是性能,而是将外部库包含在项目中的成本. (2认同)

Mar*_*som 22

您可以轻松创建表示NULL返回的静态对象.

class Attr;
extern Attr AttrNull;

class Node { 
.... 

Attr& getAttribute(const string& attribute_name) const { 
   //search collection 
   //if found at i 
        return attributes[i]; 
   //if not found 
        return AttrNull; 
} 

bool IsNull(const Attr& test) const {
    return &test == &AttrNull;
}

 private: 
   vector<Attr> attributes; 
};
Run Code Online (Sandbox Code Playgroud)

在源文件中的某处:

static Attr AttrNull;
Run Code Online (Sandbox Code Playgroud)