在C++中检查空对象

bcx*_*000 33 c++ null object

我大部分时间只和C一起工作,并且在C++中遇到了一些不熟悉的问题.

假设我在C中有这样的函数,这是非常典型的:

int some_c_function(const char* var)
{
    if (var == NULL) {
        /* Exit early so we don't dereference a null pointer */
    }
    /* The rest of the code */
}
Run Code Online (Sandbox Code Playgroud)

让我们说我正在尝试用C++编写类似的函数:

int some_cpp_function(const some_object& str)
{
    if (str == NULL)  // This doesn't compile, probably because some_object doesn't overload the == operator

    if (&str == NULL) // This compiles, but it doesn't work, and does this even mean anything?
}
Run Code Online (Sandbox Code Playgroud)

基本上,我所要做的就是在使用NULL调用some_cpp_function()时防止程序崩溃.

  • 使用对象C++执行此操作的最典型/常用方法是什么(不涉及重载==运算符)?

  • 这甚至是正确的方法吗?也就是说,我不应该编写将对象作为参数的函数,而是编写成员函数吗?(但即使如此,请回答原始问题)

  • 在一个引用一个对象的函数或一个采用C风格指针指向一个对象的函数之间,是否有理由选择一个而不是另一个?

Nav*_*een 34

基本上,我所要做的就是在使用NULL调用some_cpp_function()时防止程序崩溃.

无法使用NULL调用该函数.获得引用的目的之一是,它总是指向某个对象,因为在定义它时必须对其进行初始化.不要将引用视为花哨指针,将其视为对象本身的别名.然后就不会出现这种混乱.


Mar*_*ork 14

引用不能为NULL.界面使您可以将真实对象传递给函数.

所以不需要测试NULL.这是将引用引入C++的原因之一.

请注意,您仍然可以编写一个带指针的函数.在这种情况下,您仍然需要测试NULL.如果值为NULL,那么就像在C中一样提前返回.注意:当指针为NULL时,不应该使用异常.如果参数永远不应为NULL,则创建使用引用的接口.

  • 有时,接口采用非NULL指针而不是引用是合适的.例如,如果接口将获取所指向对象的所有权. (2认同)
  • Omnifarious:如果要指示指针的所有权转移,更合适的参数将是std :: auto_ptr.这明确指示该函数正在获取参数的所有权. (2认同)

Dav*_*eas 6

C++引用不是指针也不是Java/C#样式引用,不能为NULL.它们表现得好像是另一个现有对象的别名.

在某些情况下,如果您的代码中存在错误,您可能会获得对已经死亡或不存在的对象的引用,但您可以做的最好的事情是希望程序很快就会死掉,以便能够调试发生的事情和为什么你的程序被破坏了.

也就是说,我已经看到代码检查'null references'做类似的事情if ( &reference == 0 ),但是标准很明显,在格式良好的程序中不能有空引用.如果引用绑定到空对象,则程序格式错误,应予以纠正.如果需要可选值,请使用指针(或某些更高级别的构造boost::optional),而不是引用.


Alo*_*hal 6

就像每个人都说的那样,引用不能为空。这是因为引用是指对象。在您的代码中:

// this compiles, but doesn't work, and does this even mean anything?
if (&str == NULL)
Run Code Online (Sandbox Code Playgroud)

您正在获取对象的地址str。根据定义,str存在,因此具有地址。因此,它不可能是NULL。因此,从语法上讲,以上是正确的,但从逻辑上讲,该if条件始终为假。

关于您的问题:这取决于您想做什么。您是否希望函数能够修改参数?如果是,请传递参考。如果不是,则不要(或将引用传递给const)。有关一些良好的详细信息,请参见此C ++常见问题解答

通常,在C ++中,大多数人都喜欢通过引用传递而不是通过指针传递。原因之一就是您发现的内容:引用不是NULL,因此避免了您在函数中检查它的麻烦。


Nil*_*war 5

在引用的情况下,您可以使用特殊指定的对象作为空对象,如下所示:

class SomeClass {
    public:
        int operator==(SomeClass &object) {
            return (this == &object);
        }

    static SomeClass NullObject;
};

SomeClass SomeClass::NullObject;

void print(SomeClass &val) {
    if(val == SomeClass::NullObject)
        printf("\nNULL");
    else
        printf("\nNOT NULL");
}
Run Code Online (Sandbox Code Playgroud)