Skip to content

指针的使用前检查

为了保证安全性,你可以在使用指针的时候先进行一些检查和保护措施。但要注意的是,即使使用了这些措施,也不能保证安全。

具体实现如下:

空指针检查

如果你不确定一个指针是否为空指针,可以使用条件语句进行检查,如下所示:

if (ptr != nullptr) {
    // ...
}

或者使用 assert 宏(需要加入头文件 assert.h 或 cassert):

assert(ptr != nullptr);
// 如果 ptr 是一个空指针,将会触发运行时错误

在你调用指针时,可以使用条件语句或者三目运算符进行指针的保护措施,如下所示:

if (ptr != nullptr) {
    // 调用指针所指向对象的方法或属性
    ptr->method();
}

// 或者使用三目运算符
ptr ? ptr->method() : throw std::runtime_error("Error: null pointer");

注意:即使 ptr 不为 nullptrptr->method 也不一定是一个可调用的函数,仍有可能出错。进一步来讲,一种可能的改进写法如下:

class Base {
public:
    virtual void method() = 0;
};

class Derived : public Base {
public:
    void method() override {
        // ...
    }
};

if (dynamic_cast<Base*>(ptr) != nullptr && dynamic_cast<Base*>(ptr)->method != nullptr) {
    // 如果 ptr 指向可以调用 method() 函数的对象,则调用 method() 函数
    ptr->method();
}
else {
    throw std::runtime_error("Error: null pointer or invalid type");
}

使用 try-catch 块来处理空指针异常,如下所示:

try {
    // 调用指针所指向对象的方法或属性
    ptr->method();
} catch (std::exception& e) {
    // 处理空指针异常
    std::cerr << "Caught exception: " << e.what() << std::endl;
}

一种可能的改进写法如下:

try {
    if (ptr != nullptr) {
        // 尝试调用 method 函数
        ptr->method();
    } else {
       // 抛出空指针异常
       throw std::runtime_error("Error: null pointer");
    }
} catch (const std::bad_function_call& e) {
    // 处理方法调用异常
    std::cerr << "Caught exception: " << e.what() << std::endl;
} catch (const std::runtime_error& e) {
    // 处理空指针异常
    std::cerr << "Caught runtime error: " << e.what() << std::endl;
} catch (const std::exception& e) {
    // 处理其他异常
    std::cerr << "Caught exception: " << e.what() << std::endl;
}