有一个c ++代码如下所示:
class Metadata : public MetaspaceObj {
void print_value_on_maybe_null(outputStream* st) const {
if (this == NULL)
st->print("NULL");
else
print_value_on(tty);
}
}
我只是想知道在C ++对象中'这个'怎么可能是NULL。可能有可能吗?
上面的代码摘自jdk8 / openjdk / hotspot / src / share / vm / oops / metadata.hpp。
答案 0 :(得分:2)
在C ++中,您实际上可以取消引用并在NULL
指针上调用成员函数。
考虑:
Metadata* pointer = nullptr;
pointer->print_value_on_maybe_null(...);
上面的代码是有效的C ++代码,它编译得很好。这样做的问题在于它会导致undefined behavior。
回到问题中的代码,我认为在过去的某个时间,某个地方有一个错误会导致在空指针上调用成员函数,而不是试图找到并修复根本原因对于问题,作者刚刚添加了this == NULL
的检查。
答案 1 :(得分:1)
从技术上讲,不允许在空指针上调用方法;这样的事情是未定义的行为:
Metadata * foo = NULL;
foo->print_value_on_maybe_null(NULL);
因此,在这种情况下,允许编译器做任何想做的事情。
但只要该方法不是虚拟的,典型的编译器就不会费心包括foo
非空的任何检查,因为不需要进行这样的检查。 (当然,使用虚方法,它必须检查foo
以检索vtable并调用适当的方法版本。)所以。 。 。是的,这很有可能,但前提是调用代码有错误(或许多程序员认为是bug)。
答案 2 :(得分:0)
在NULL实例上调用方法是未定义的行为。
也就是说,如果您写下以下内容,大多数编译器都不会做任何奇怪的事情:
Metadata *x = NULL;
x->print_value_on_maybe_null(&os);
但是你走得有点紧张。