You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在编译期阻止类构造函数接收NULL指针?

编译期阻止类接收NULL指针的方案

针对你提出的需求,以下几种方案可以在编译期强制类A的构造函数接收非空指针,同时避免每个成员函数都做空指针检查:

方案1:改用引用替代指针

C++中的引用编译期就必须绑定到有效对象,无法为null,是最直接的解决方案。只需修改构造函数参数类型,同时初始化内部指针:

class B
{
    // 类B的API
};

class A
{
private:
    B* ptrB_; // 或直接使用B& refB_;
public:
    // 构造函数接收B的引用,确保传入非空对象
    explicit A(B& b) : ptrB_(&b) {}

    void Func1()
    {
        // 无需空指针检查,ptrB_必然指向有效对象
        // ... 原有逻辑
    }
};

int main()
{
    B tempB;
    A tempA(tempB); // 正确:传入有效对象的引用

    // 以下代码会编译报错,无法传入空值
    // A invalidA(nullptr);
    // B* nullPtr = nullptr;
    // A invalidA(*nullPtr);
}

这种方案无需额外依赖,编译期直接阻断空值传入,代码最简洁。

方案2:使用std::not_null(C++17及以上)

如果必须保留指针类型,可以用C++17标准库的std::not_null(或早期GSL库的gsl::not_null)包装指针,它会在编译期检查常量空值,运行期兜底检查变量空值:

#include <memory> // C++17引入std::not_null

class B
{
    // 类B的API
};

class A
{
private:
    std::not_null<B*> ptrB_;
public:
    explicit A(std::not_null<B*> ptrB) : ptrB_(ptrB) {}

    void Func1()
    {
        // 无需空指针检查,ptrB_保证非空
        // ... 原有逻辑
    }
};

int main()
{
    B tempB;
    A tempA(&tempB); // 正确:传入有效指针

    // 以下代码编译期报错
    // A invalidA(nullptr);
}

如果传入运行期生成的空指针(如某个函数返回null),std::not_null会触发断言或抛出异常,避免后续逻辑出错。

方案3:禁用nullptr构造重载(兼容旧标准)

如果使用C++17之前的版本,可以通过删除std::nullptr_t参数的构造函数重载,在编译期阻止显式传入nullptr,同时保留运行期的断言兜底:

#include <cassert>

class B
{
    // 类B的API
};

class A
{
private:
    B* ptrB_;
public:
    explicit A(B* ptrB) : ptrB_(ptrB)
    {
        // 运行期兜底检查,防止传入运行期生成的空指针
        assert(ptrB_ != nullptr && "ptrB cannot be null");
    }

    // 删除接收nullptr的构造函数,编译期阻止空值传入
    A(std::nullptr_t) = delete;
};

int main()
{
    B tempB;
    A tempA(&tempB); // 正确

    // 以下代码编译报错
    // A invalidA(nullptr);
}

这种方案兼容C++11及以上版本,既能在编译期阻止显式nullptr,又能通过断言捕获运行期意外的空指针。


内容的提问来源于stack exchange,提问作者Shanti Schul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 18:45:30