在 C++ 中检查空对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2099882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:06:23  来源:igfitidea点击:

Checking for a null object in C++

c++objectnull

提问by bcx_2000

I've mostly only worked with C and am running into some unfamiliar issues in C++.

我大部分时间只使用 C,并且在 C++ 中遇到了一些不熟悉的问题。

Let's say that I have some function like this in C, which would be very typical:

假设我在 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 */
}

And let's say that I'm trying to write a similar function in C++:

假设我正在尝试用 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?
}

Basically, all I'm trying to do is to prevent the program from crashing when some_cpp_function() is called with NULL.

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

  • What is the most typical/common way of doing this with an object C++ (that doesn't involve overloading the ==operator)?

  • Is this even the right approach? That is, should I not write functions that take an object as an argument, but rather, write member functions? (but even if so, please answer the original question)

  • Between a function that takes a reference to an object, or a function that takes a C-style pointer to an object, are there reasons to choose one over the other?

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

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

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

采纳答案by Naveen

Basically, all I'm trying to do is to prevent the program from crashing when some_cpp_function() is called with NULL.

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

It is not possible to call the function with NULL. One of the purpose of having the reference, it will point to some object always as you have to initialize it when defining it. Do not think reference as a fancy pointer, think of it as an alias name for the object itself. Then this type of confusion will not arise.

不能用 NULL 调用函数。拥有引用的目的之一是,它将始终指向某个对象,因为您必须在定义它时对其进行初始化。不要将引用视为一个花哨的指针,将其视为对象本身的别名。那么这种混淆就不会出现了。

回答by Martin York

A reference can not be NULL. The interface makes you pass a real object into the function.

引用不能为 NULL。该接口使您可以将真实对象传递给函数。

So there is no need to test for NULL. This is one of the reasons that references were introduced into C++.

所以没有必要测试NULL。这是将引用引入 C++ 的原因之一。

Note you can still write a function that takes a pointer. In this situation you still need to test for NULL. If the value is NULL then you return early just like in C. Note: You should not be using exceptions when a pointer is NULL. If a parameter should never be NULL then you create an interface that uses a reference.

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

回答by David Rodríguez - dribeas

A C++ reference is not a pointer nor a Java/C# style reference and cannot be NULL. They behave as if they were an alias to another existing object.

C++ 引用既不是指针也不是 Java/C# 样式引用,并且不能为 NULL。它们的行为就像是另一个现有对象的别名。

In some cases, if there are bugs in your code, you might get a reference into an already dead or non-existent object, but the best thing you can do is hope that the program dies soon enough to be able to debug what happened and why your program got corrupted.

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

That is, I have seen code checking for 'null references' doing something like: if ( &reference == 0 ), but the standard is clear that there cannot be null references in a well-formed program. If a reference is bound to a null object the program is ill-formed and should be corrected. If you need optional values, use pointers (or some higher level construct like boost::optional), not references.

也就是说,我已经看到代码检查“空引用”执行以下操作:if ( &reference == 0 ),但标准很清楚,在格式良好的程序中不能有空引用。如果引用绑定到空对象,则程序格式错误,应该更正。如果您需要可选值,请使用指针(或一些更高级别的构造,如boost::optional),而不是引用。

回答by Alok Singhal

As everyone said, references can't be null. That is because, a reference refers to an object. In your code:

正如大家所说,引用不能为空。那是因为,引用指向一个对象。在您的代码中:

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

you are taking the address of the object str. By definition, strexists, so it has an address. So, it cannot be NULL. So, syntactically, the above is correct, but logically, the ifcondition is always going to be false.

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

About your questions: it depends upon what you want to do. Do you want the function to be able to modify the argument? If yes, pass a reference. If not, don't (or pass reference to const). See this C++ FAQfor some good details.

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

In general, in C++, passing by reference is preferred by most people over passing a pointer. One of the reasons is exactly what you discovered: a reference can't be NULL, thus avoiding you the headache of checking for it in the function.

通常,在 C++ 中,大多数人更喜欢通过引用传递而不是传递指针。原因之一正是您所发现的:引用不能是NULL,从而避免您在函数中检查它的麻烦。

回答by Nilesh Pawar

You can use a special designated object as the null object in case of references as follows:

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

class SomeClass
{
    public:

        int operator==(SomeClass &object)
        {
            if(this == &object) 
            {
                    return true;
            }

            return false;
        }


    static SomeClass NullObject;
};

SomeClass SomeClass::NullObject;

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

回答by Nilesh Pawar

  • What is the most typical/common way of doing this with an object C++ (that doesn't involve overloading the == operator)?
  • Is this even the right approach? ie. should I not write functions that take an object as an argument, but rather, write member functions? (But even if so, please answer the original question.)
  • 使用对象 C++ 执行此操作的最典型/最常见的方法是什么(不涉及重载 == 运算符)?
  • 这甚至是正确的方法吗?IE。我不应该编写将对象作为参数的函数,而是编写成员函数吗?(但即使是这样,请回答最初的问题。)

No, references cannot be null (unless Undefined Behavior has already happened, in which case all bets are already off). Whether you should write a method or non-method depends on other factors.

不,引用不能为空(除非未定义行为已经发生,在这种情况下,所有赌注都已关闭)。您应该编写方法还是非方法取决于其他因素。

  • Between a function that takes a reference to an object, or a function that takes a C-style pointer to an object, are there reasons to choose one over the other?
  • 在接受对象引用的函数或接受指向对象的 C 风格指针的函数之间,是否有理由选择一个而不是另一个?

If you need to represent "no object", then pass a pointer to the function, and let that pointer be NULL:

如果您需要表示“无对象”,则将指针传递给该函数,并让该指针为 NULL:

int silly_sum(int const* pa=0, int const* pb=0, int const* pc=0) {
  /* Take up to three ints and return the sum of any supplied values.

  Pass null pointers for "not supplied".

  This is NOT an example of good code.
  */
  if (!pa && (pb || pc)) return silly_sum(pb, pc);
  if (!pb && pc) return silly_sum(pa, pc);
  if (pc) return silly_sum(pa, pb) + *pc;
  if (pa && pb) return *pa + *pb;
  if (pa) return *pa;
  if (pb) return *pb;
  return 0;
}

int main() {
  int a = 1, b = 2, c = 3;
  cout << silly_sum(&a, &b, &c) << '\n';
  cout << silly_sum(&a, &b) << '\n';
  cout << silly_sum(&a) << '\n';
  cout << silly_sum(0, &b, &c) << '\n';
  cout << silly_sum(&a, 0, &c) << '\n';
  cout << silly_sum(0, 0, &c) << '\n';
  return 0;
}

If "no object" never needs to be represented, then references work fine. In fact, operator overloads are much simpler because they take overloads.

如果永远不需要表示“无对象”,则引用工作正常。事实上,运算符重载要简单得多,因为它们接受重载。

You can use something like boost::optional.

你可以使用类似 boost::optional 的东西。

回答by sharptooth

C++ references naturally can't be null, you don't need the check. The function can only be called by passing a reference to an existing object.

C++ 引用自然不能为空,不需要检查。该函数只能通过传递对现有对象的引用来调用。

回答by Nikola Smiljani?

You should use NULL only with pointers. Your function accepts a reference and they can't be NULL.

您应该只对指针使用 NULL。您的函数接受引用并且它们不能为 NULL。

Write your function just like you would write it in C.

像在 C 中编写函数一样编写函数。