我从维基百科上读到:
“引用不能为null,而指针可以为;每个引用都指某个对象,尽管它可能有效也可能无效。“
但是我不相信因为下面的代码看看它编译器没有给出错误:
class person
{
public:
virtual void setage()=0;
};
main()
{
person *object=NULL;
person &object1=*object;
}
请详细说明这一点。
答案 0 :(得分:20)
在您的代码中:
person *object=NULL;
person &object1=*object;
您取消引用NULL指针,因此您将获得未定义的行为。要回答你的问题,就没有NULL引用这样的东西。
为了解决问题的其他部分,仅仅因为程序编译,不能保证它是正确的或它会起作用。 C ++编译器甚至不需要尝试诊断代码所包含的错误类型。
答案 1 :(得分:9)
说person &object1=*object
与说person &object1=NULL
不是一回事。可能编译器不够聪明,无法发现您正在解除引用空指针,但无论如何您都会遇到运行时错误。所以它们仍然是真实的;)
答案 2 :(得分:4)
你可以有一个空引用,不知道为什么有人会这么说,这是一些操作的令人讨厌的副作用。你不能直接创建一个。
答案 3 :(得分:3)
会导致程序崩溃。你试过试试吗? 执行*对象将取消引用空指针,因此实际上您的引用永远不会被赋值。
答案 4 :(得分:2)
好吧,你可以在C ++中做任何你想要的事情。另一个例子:
person &object1 = *( reinterpret_cast<person*>(0) );
除了你提到的情况之外,你在上面的案例中调用了一个未定义的行为!
答案 5 :(得分:1)
clang 3.5甚至警告可能稍后对引用进行NULL检查:
/tmp/person.C:11:6: warning: reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to
always convert to true [-Wundefined-bool-conversion]
if (&object1) {}
~~ ^~~~~~~
1 warning generated.
答案 6 :(得分:0)
gcc8会对此发出警告:
警告:编译器可以假定'object1'的地址永远不会为NULL [-Waddress]
一个小演示:
#include <iostream>
class person
{
public:
virtual void setage()=0;
};
int main()
{
person *object=NULL;
person &object1=*object;
if (&object1 == NULL) {
std::cout << "NULL object1" << std::endl;
}
if (!(&object1)) {
std::cout << "NULL object1 " << std::endl;
}
}
编译并运行输出:
g ++ -std = c ++ 2a -pthread -fgnu-tm -O2 -Wall -Wextra -pedantic -pthread -pedantic-errors main.cpp -lm -latomic -lstdc ++ fs && ./a.out
main.cpp:在函数'int main()'中:
main.cpp:14:18:警告:编译器可以假定 'object1'永远不会为NULL [-Waddress]
if (&object1 == NULL) { ^
main.cpp:18:19:警告:编译器可以假定 'object1'永远不会为NULL [-Waddress]
if (!(&object1)) { ^
NULL object1
NULL object1