避免在 C++ 中进行空指针检查
Posted
技术标签:
【中文标题】避免在 C++ 中进行空指针检查【英文标题】:Avoid null pointer checks in C++ 【发布时间】:2009-03-30 17:44:48 【问题描述】:用例:
class B
int b;
public:
int getB()
return b;
;
class A
B *b;
public:
int getB()
if (b ) //How can I avoid the null check for b here
return b->getB();
【问题讨论】:
为什么要避免空指针检查? 是的,很高兴知道您要实现什么...优化?更简洁的代码? 空检查不是在错误的地方吗? getB() 需要返回 B,或者...... null(它还会返回什么?) 【参考方案1】:如果 B 为 null 然后在 getB() 中,您期望会发生什么?如果它不是您的程序的有效状态,只需断言(b!= NULL)。如果是有效状态,则需要检查。
某些语言支持契约,因此您无需手动编写检查代码,但不幸的是 C++ 不支持。
【讨论】:
【参考方案2】:解决方案 1:尽可能使用引用。
解决方案 2:只需执行空指针检查并让编译器处理它们。如今,删除多余的空指针检查是一种标准优化。除了大部分冗余之外,它们没有捕获所有冗余。
【讨论】:
【参考方案3】:你有很多选择。这里有 5 个。
解决方案 1: 将 B 的引用而不是指针传递给 A。
虽然可以引用 NULL 对象。这真的很难做到,你不需要检查它。
class A
B &b;
public:
A (B& b_) : b(b_)
int getB()
return b.getB();
;
解决方案 2:不要因此而牺牲类的关系设计,但它可能适用。
从 B 派生类 A。然后您可以简单地调用 getB()。
解决方案 3:也许您根本不应该使用指针,而只是让 B 成为 A 的成员。
class A
B b;
public:
int getB()
return b.getB();
;
解决方案 4:立即断言以避免以后的检查
class A
B *b;
public:
A (B* pb) : b(pb)
assert(pb != NULL);
int getB()
return b->getB();
;
解决方案 5:有一个你使用的默认 B
class A
B *pb;
B defaultB;
public:
A () : pb(&defaultB)
void setB(B* pb_)
if(pb != NULL)
pb = pb_;
int getB()
return pb->getB();
;
【讨论】:
"虽然可以引用一个 NULL 对象" 不,在符合 C++ 的情况下不可能有一个空引用。【参考方案4】:正如 Brian Bondy 所提到的,参考是一种基于语言的方法。我知道的唯一另一个避免空检查的选项是Null Object Pattern。当然,这意味着对如何获取 B 对象进行更多的工作和控制。
【讨论】:
【参考方案5】:// case: you expect *b can be 0
class A
B *b;
public:
int getB()
return b ? b->getB() : getDefaultValue();
// case: there is shouldn't be a chance *b can be 0
class AA
B *b;
public:
AA( B *bValue ):
b(bValue)
assert( b );
int getB()
return b->getB();
;
【讨论】:
以上是关于避免在 C++ 中进行空指针检查的主要内容,如果未能解决你的问题,请参考以下文章