Why is there no “NULL reference” in C++?

一个人想着一个人 提交于 2019-12-04 03:58:40

Because a reference carries the semantic that it points to a valid memory address that never changes; i.e. that dereferencing it is safe/defined and so no NULL checks are required. References cannot be reassigned by design.

You use a pointer when the var can be NULL and client code has to handle that case. You use a reference when you can guarantee a valid/initialised memory address.

One example of using pointers is as a member of a class to store a "reference" to some instance that might not be known or able to be initialised at class construction time. However, member references must be initialised at construction time (via initialiser lists) and their assignment cannot be deferred.

If you allow a null reference it is then no different to a pointer besides syntax (the same NULL checks would need to take place.)

Update:

"And, in most OOP languages, objects can be NULL - Pascal, C#, Java, JavaScript, PHP, etc. [...] So why is C++ somehow special and doesn't have a NULL object? Was it just an overlook or an actual decision?"

I think you are a bit confused about this. Java and C# etc. might give the impression of "NULL objects", but these object references are more or less like a C++ pointer with simpler syntax, GC instrumentation and exception throwing. In those languages if you operate on a "Null Object" you will get some kind of exception like NullReferenceException (C#). Hell, in Java its called a NullPointerException.

You have to check for null before you can use them safely. Kind of like C++ pointers (except in most managed languages, pointers are initialised to NULL by default, whereas in C++ its usually up to you to take care of setting the initial pointer value (otherwise undefined/whatever memory was already there)).

The C++ view is about having choice, and hence being verbose:

  • Use a plain pointer to do how you please, checking NULL where necessary.
  • Use references which have a compiler-enforced validity semantic/constraint.
  • Roll your own smart pointers that do bookkeeping and behave whichever way you want them to.
  • Using void pointers (cautiously!) to reference an untyped block of memory if ever required.

Please have a look at differences between pointers and references - while the standard leaves it open how references are implemented, they are at the moment always implemented as pointers.

Which means that the main difference between them is a) semantics b) pointers can be reseated c) pointers can be null.

So the short answer is, this was done on purpose. When you as programmer see a reference you should know that a) that reference is populated b) it won't change (and c) you can use it with the same semantics as an object).

Would the standard allow a null reference, you would always have to check for null before using a reference, which was not wanted.

Edit:

Regarding your edit, I guess the confusion here might stem from the fact that most simpler OO languages hide what is going on. To take Java as example, while it looks like you have NULL objects, and can assign them, you really can't - what is really going on is that Java only has pointers, and can assign null values to those pointers. Since it is impossible to actually have objects directly in Java, they do away with pointer semantics and treat the pointer as the object. C++ is simply more powerful - and error prone (Java enthusiast would say that stack user class instances are not required, and the decision to not have them in Java was driven to reduce complexity, and make Java easier to use). It also follows that, since Java doesn't have objects, it doesn't have references. What really doesn't help, though, is that Java calls what a C++ person would call a pass-by-value of a pointer a pass-by-reference.

A C++ reference is not a reference in the sense that most other languages use the term; it is more like an alias. Using a C++ reference does not involve "dereferencing" it in the same way you dereference a pointer; it effectively is the object assigned to it.

There isn't really such a thing as a null object instance, so you can't create a C++ reference to such a thing. In other languages a null reference is the equivalent of a C++ null pointer; it doesn't actually contain anything.

Now, regarding your other thoughts: 1. having un-nullable references is a good thing to my mind; it means you get all the benefits of passing by reference with none of the requirement to check for nulls all over the place. 2. nullable references do not replace pointers... if you need to do memory or IO work at a low level, you're going to want raw access to memory and memory-mapped devices. You can take a look at C# (or C++/CLR), which has managed references and unmanaged pointers for precisely this reason.

Reference by definition should be associated with another variable or object. So an empty or null reference sort of violates it purpose of existence.

Technically that would mean you start with a null reference, then ASSIGN it to some variable or may be latter reassign to another variable. This is simply NOT what reference was meant to be created for.

There are several other uses of pointers that reference can simply not replicate. Such as referring to a large chunk of complex data (a sequence of bytes) with a small amount of memory using a pointer and pass that around as frequently as needed by spending only 8 bytes or so for pointer. You cannot do that with a reference without wasting equal memory.

Reference would always be tied to a type, which is not the case with pointer.

Reference must refer to something, so, null reference is not available.
C has no references and we can use only pointers in this language, so, this is compatibility with C language

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!