Sta*_*123 3 c++ oop pointers exception
#include <iostream>
struct X
{
bool isNull() { return this == nullptr; }
bool isNullConst() const { return this == nullptr; }
};
bool isNull(X& x) { return &x == nullptr; }
bool isNullConst(const X& x) { return &x == nullptr; }
// always false or exception.
bool isNullCopy(X x) { return &x == nullptr; }
int main()
{
X* x = nullptr;
std::cout << x->isNull() << '\n';
std::cout << (*x).isNull() << '\n';
std::cout << isNull(*x) << '\n';
// std::cout << isNull2(*x) << '\n'; // exception.
}
Run Code Online (Sandbox Code Playgroud)
在这里,我知道X::isNull()相当于isNull(X&)并且X::isNullConst()相当于isNullConst(const X&)。
我不知道的是,取消引用空指针是正常的。我认为对空指针的任何取消引用都会导致异常。
玩了一会儿指针后,我得出结论,解引用空指针本身不是问题,问题在于尝试读取或写入空指针指向的地址。
并且由于函数位于内存中众所周知的位置,取消对类的空指针的引用并调用其中的一个函数只会导致以空对象作为第一个参数来调用该函数。
这对我来说是新的,但这可能不是完整的画面。
起初我以为这是一个 OOP 概念,因此它应该在例如 java 中工作,但它在这里不起作用并导致异常(这让我想为什么它在 java 中不起作用?... ):
class X
{
boolean isNull() { return this == null; }
}
public class Main {
public static void main(String[] args) {
X x = null;
System.out.println(x.isNull());
}
}
Run Code Online (Sandbox Code Playgroud)
所以,显然这与 C++ 相关,而不是一般的 OOP。
在哪些情况下取消引用空指针是有效的并且不会导致异常?
除了结构和类的指针之外,还有什么可以成功解除引用的,即使它们是空指针?
另外,为什么在不访问其字段的情况下调用空指针的函数会在其他语言(如 java)中引发异常?
例如,取消引用空指针有意义的一种情况是在红黑树中。空指针被认为是黑色的。
#define RED true
#define BLACK false;
struct Node
{
bool color;
bool isRed()
{
return this != nullptr && this->color == RED;
}
};
bool isRed(Node* node)
{
return node != nullptr && node->color == RED;
}
Run Code Online (Sandbox Code Playgroud)
在这里,我认为将函数包含在Node类本身中更有意义,因为它与它相关。除了检查它是否为空的逻辑之外,将与节点相关的所有逻辑都包含在其中并不是很方便。
我认为对空指针的任何取消引用都会导致异常。
C++ 不是 Java。C++ 确实有例外,但它们仅用于特殊情况,而不是到处使用(如在 Java 中)。您应该知道取消引用空指针是不允许的,并且编译器假定它永远不会在正确的代码中发生。如果它仍然发生,您的代码无效。
阅读未定义行为。当你想用 C++ 做任何严肃的事情时,了解它是必不可少的。
有效取消引用空指针的规则是什么?
规则是:你不能这样做。当你这样做时,你的代码格式错误,不需要诊断。这是另一种说法:您的代码具有未定义的行为。编译器不需要发出错误或警告,当您要求编译器编译错误的代码时,结果可以是任何东西。