lau*_*ent 8 c++ null pointers specifications reference
我正在阅读C++ FAQ - " 8.6 - 我何时应该使用引用,何时应该使用指针? "特别是这句话:
尽可能使用引用,并在必要时使用指针.
...
上面的例外是函数的参数或返回值需要"sentinel"引用 - 一个不引用对象的引用.这通常最好通过返回/获取指针,并赋予NULL指针这一特殊意义(引用必须始终为别名对象,而不是取消引用的NULL指针).
从我所看到的,对"哨兵"引用的需求确实经常是使用指针而不是引用的原因.我想知道的是:为什么C++没有特殊的"NULL值"用于引用?它似乎会使指针几乎不必要,这将解决许多问题.
那么为什么它不是语言规范的一部分呢?
编辑:
我不确定我的问题是否清楚 - 我想我不是故意要求NULL引用.我经常在C++中读到"引用是对象".而且,在大多数OOP语言中,对象可以是NULL -帕斯卡尔,C#,Java和JavaScript的,PHP等,所有这些,你可以做someObject = null或someObject := nil.事实上,Pascal也支持指针,但仍然允许对象nil,因为它有它的用途.那么为什么C++在某种程度上是特殊的并且没有NULL对象呢?这只是一个忽视还是一个实际的决定?
Pre*_*eti 13
因为引用带有它指向永远不会改变的有效内存地址的语义; 即解除引用它是安全/定义的,因此不需要进行NULL检查.参考不能通过设计重新分配.
当var可以为NULL并且客户端代码必须处理该情况时,您使用指针.如果可以保证有效/初始化的内存地址,则使用引用.
使用指针的一个示例是作为类的成员,用于存储某些实例的"引用",这些实例可能在类构造时未知或无法初始化.但是,成员引用必须在构建时初始化(通过初始化列表),并且不能推迟其分配.
如果允许空引用,那么除了语法之外,它与指针没有区别(需要进行相同的NULL检查.)
更新:
"而且,在大多数OOP语言中,对象可以是NULL - Pascal,C#,Java,JavaScript,PHP等等.[...]那么为什么C++有些特殊并且没有NULL对象呢?它只是一个忽视还是一个实际的决定呢?"
我觉得你对此有点困惑.Java和C#等可能会给人一种"NULL对象"的印象,但这些对象引用或多或少类似于C++指针,具有更简单的语法,GC检测和异常抛出.在这些语言中,如果您使用"Null对象",您将获得某种异常,如NullReferenceException(C#).地狱,在Java中它被称为NullPointerException.
您必须先检查,null然后才能安全使用它们.有点像C++指针(除了在大多数托管语言中,默认情况下指针初始化为NULL,而在C++中,它通常取决于您设置初始指针值(否则未定义/已存在的任何内存)).
C++视图是关于选择的,因此是冗长的:
请看一下指针和引用之间的区别 - 虽然标准让它打开了如何实现引用,但它们目前始终是作为指针实现的.
这意味着它们之间的主要区别是a)语义b)指针可以重新安装c)指针可以为null.
所以简短的回答是,这是故意的.当您作为程序员看到引用时,您应该知道a)该引用已填充b)它不会更改(和c)您可以使用与对象相同的语义).
如果标准允许空引用,则在使用引用之前总是必须检查null,这是不需要的.
编辑:
关于你的编辑,我想这里的混乱可能源于这样一个事实,即大多数更简单的OO语言隐藏了正在发生的事情.以Java为例,虽然看起来你有NULL对象,并且可以分配它们,但你真的不能 - 真正发生的是Java只有指针,并且可以为这些指针分配空值.由于不可能直接在Java中实现对象,因此它们取消了指针语义并将指针视为对象.C++功能更强大 - 容易出错(Java爱好者会说不需要堆栈用户类实例,并且决定不在Java中使用它们来降低复杂性,并使Java更易于使用).由此可见,由于Java没有对象,因此它没有引用.但是,实际上没有帮助的是Java调用C++人称为指针传递值的传递方式.