何时使用optional<not_null<T*>>?为何不直接用裸指针?
关于
optional<not_null<T*>>的使用场景疑问解答 先明确核心问题:既然optional表示值可能不存在,not_null表示值存在时非空,为什么不直接用裸指针?答案在于语义精准性和安全检查这两个关键优势:
1. 语义完全明确,没有歧义
not_null<T*>的意义是:只要这个指针存在,就绝对不会是空指针,从根源上排除了“有效但为空”的可能性。optional的意义是:这个值可能完全不存在。- 两者组合起来,就是“要么没有值,要么有一个绝对非空的有效指针”——这个语义比裸指针清晰一万倍。裸指针的问题在于它的语义模糊:你永远不确定它是“必须非空的指针”还是“可能为空的可选指针”,阅读代码的人要花额外精力去猜,写代码的人也容易犯迷糊。
2. 借助静态检查避免低级错误
not_null<T*>会在编译期拦截所有试图把空指针赋值给它的操作,比如你写not_null<int*> p = nullptr;直接编译失败,而裸指针不会管这个,很容易不小心传入空指针导致运行时崩溃。- 当你处理
optional<not_null<T*>>时,必须先通过has_value()或者operator bool()检查是否有值,确认有值之后,内部的not_null<T*>可以直接使用,完全不用再做空指针判断——既减少了冗余代码,又避免了漏写空检查的风险。
3. 接口契约更清晰
作为函数参数或返回值时,optional<not_null<T*>>相当于给调用者立了一个明确的契约:
这个结果/参数可能不存在,但如果存在,它一定是一个有效的非空指针。
而裸指针做不到这一点:调用者永远要纠结“我要不要给这个指针做空检查?空指针是合法情况吗?”,很容易因为理解偏差写出bug。
对比直接用裸指针的问题
裸指针的模糊语义是最大的问题:它既可以承担“可选(允许空)”的角色,也可以承担“必须非空”的角色。而optional<not_null<T*>>把这两个语义拆解得明明白白,让代码的意图从类型上就能体现出来,同时借助not_null的静态检查,从编译阶段就消灭了空指针的隐患——这比依赖程序员的自觉靠谱得多。
内容的提问来源于stack exchange,提问作者janovak
相关产品推荐
相关产品推荐

