在 C++ 中抛出 NullPointerException
Throwing a NullPointerException in C++
是否可以让 C++ 在对 nullptr 对象调用方法时抛出 NPE,而不是进入未定义的行为?我可以为 SEGFAULT 信号创建处理程序,但这真的很危险,因为并非每个 SEGFAULT 都是 NullPointerException。如果我必须通过检查 if 子句来做到这一点,是否有有效的方法来做到这一点?也许也在编译时?
是的,你可以,但这不是一个好主意(无论如何你都不应该处理指针,在现代 C++ 中,指针保存在管理其生命周期的对象中)。
您始终可以定义一个 class 来保存指针。然后,当您尝试使用 operator->()
时,如果持有的指针是 nullptr
,它将抛出。
template<typename T>
class ThrowingUniquePtr
{
T* ptr;
public:
// STUFF to create and hold pointer.
T* operator->()
{
if (ptr) {
return ptr;
}
throw NullPointerException; // You have defined this somewhere else.
}
};
class Run
{
public:
void run() {std::cout << "Running\n";}
};
int main()
{
ThrowingUniquePtr<Run> x(new Run);
x->run(); // will call run.
ThrowingUniquePtr<Run> y(nullptr);
y->run(); // will throw.
}
另一种异常处理方式:
使用 NULL 指针调用函数
#include <iostream>
#include <typeinfo>
using namespace std;
char str_NullPointer[25] = "NULL Pointer exception";
char str_Arithmetic[25] = "Arithmetic exception";
class A
{
public:
int i = 20;
public:
int function()
{
printf("Function start\n");
try
{
if (this)
{
printf("value of i = %d \n", i);
}
else
{
throw str_NullPointer; /* Exception thrown in Case 2 */
}
}
catch(const int s)
{
printf("%d\n", s);
}
catch(const char* s)
{
printf("%s in %s\n", s, typeid(this).name()); /* Exception and Class Name */
}
printf("Function end\n\n\n");
}
};
int main() {
//code
printf("Case 1: With Pointer\n");
A *obj = new A();
obj->i = 20;
obj->function();
printf("Case 2: With NULL Pointer\n");
delete obj;
obj = NULL;
obj->function();
return 0;
}
输出:
Case 1: With Pointer
Function start
value of i = 20
Function end
Case 2: With NULL Pointer
Function start
NULL Pointer exception in P4abcd
Function end
是否可以让 C++ 在对 nullptr 对象调用方法时抛出 NPE,而不是进入未定义的行为?我可以为 SEGFAULT 信号创建处理程序,但这真的很危险,因为并非每个 SEGFAULT 都是 NullPointerException。如果我必须通过检查 if 子句来做到这一点,是否有有效的方法来做到这一点?也许也在编译时?
是的,你可以,但这不是一个好主意(无论如何你都不应该处理指针,在现代 C++ 中,指针保存在管理其生命周期的对象中)。
您始终可以定义一个 class 来保存指针。然后,当您尝试使用 operator->()
时,如果持有的指针是 nullptr
,它将抛出。
template<typename T>
class ThrowingUniquePtr
{
T* ptr;
public:
// STUFF to create and hold pointer.
T* operator->()
{
if (ptr) {
return ptr;
}
throw NullPointerException; // You have defined this somewhere else.
}
};
class Run
{
public:
void run() {std::cout << "Running\n";}
};
int main()
{
ThrowingUniquePtr<Run> x(new Run);
x->run(); // will call run.
ThrowingUniquePtr<Run> y(nullptr);
y->run(); // will throw.
}
另一种异常处理方式: 使用 NULL 指针调用函数
#include <iostream>
#include <typeinfo>
using namespace std;
char str_NullPointer[25] = "NULL Pointer exception";
char str_Arithmetic[25] = "Arithmetic exception";
class A
{
public:
int i = 20;
public:
int function()
{
printf("Function start\n");
try
{
if (this)
{
printf("value of i = %d \n", i);
}
else
{
throw str_NullPointer; /* Exception thrown in Case 2 */
}
}
catch(const int s)
{
printf("%d\n", s);
}
catch(const char* s)
{
printf("%s in %s\n", s, typeid(this).name()); /* Exception and Class Name */
}
printf("Function end\n\n\n");
}
};
int main() {
//code
printf("Case 1: With Pointer\n");
A *obj = new A();
obj->i = 20;
obj->function();
printf("Case 2: With NULL Pointer\n");
delete obj;
obj = NULL;
obj->function();
return 0;
}
输出:
Case 1: With Pointer
Function start
value of i = 20
Function end
Case 2: With NULL Pointer
Function start
NULL Pointer exception in P4abcd
Function end