用例:
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();
}
}
}
答案 0 :(得分:8)
如果B在getB()中为null,您期望发生什么?如果它不是程序的有效状态,只需断言(b!= NULL)。如果它是有效状态,则需要检查。
有些语言支持合同,因此您不需要手动编写检查代码,但遗憾的是C ++没有。
答案 1 :(得分:6)
解决方案1:尽可能使用参考。
解决方案2:只需执行空指针检查,让编译器关注它们。如今,删除冗余空指针检查是标准的优化。除了大部分冗余之外,它们并没有完全捕获。
答案 2 :(得分:2)
你有很多选择。这是5.
解决方案1:将B的引用传递给A而不是指针。
虽然可以引用NULL对象。这真的很难,而且你不需要检查它。
class A
{
B &b;
public:
A (B& b_) : b(b_)
{
}
int getB()
{
return b.getB();
}
};
解决方案2:不要因此而牺牲类的关系设计,但它可能适用。
让A级派生自B.然后你可以简单地调用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();
}
};
答案 3 :(得分:0)
正如Brian Bondy所提到的,参考文献是一种基于语言的方式。为了避免空值检查,我唯一知道的另一个选项是Null Object Pattern。当然,这意味着需要更多的工作和控制你如何获得B对象。
答案 4 :(得分:0)
// 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();
}
};