避免在C ++中进行空指针检查

时间:2009-03-30 17:44:49

标签: c++ pointers

用例:

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();
              }
          }
  }

5 个答案:

答案 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();
    }
};