tags:

views:

709

answers:

5

Use case:

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();
              }
          }
  }
+1  A: 

You have a lot of options. Here are 5.

Solution 1: Pass a reference of B to A instead of a pointer.

Although it is possible to have a reference to a NULL object. It's really hard to do, and you don't need to check for it.

class A 
{
  B &b;
public:
  A (B& b_) : b(b_)
  {
  }

  int getB() 
  {
    return b.getB();
  }
};


Solution 2: Don't sacrifice the relationship design of your classes with this, but it may be applicable.

Have class A derived from B. Then you can simply call getB().


Solution 3: Perhaps you shouldn't use a pointer at all and simply make B a member of A.

class A 
{
  B b;

public:
  int getB() 
  {
    return b.getB();
  }
};


Solution 4: Assert right away to avoid later checks

class A 
{
  B *b;
public:
  A (B* pb) : b(pb)
  {
    assert(pb != NULL);
  }

  int getB() 
  {
    return b->getB();
  }
};


Solution 5: Have a default B that you use

class A 
{
  B *pb;
  B defaultB;
public:
  A () : pb(&defaultB)
  {
  }

  void setB(B* pb_)
  {
    if(pb != NULL)
      pb = pb_;
  }

  int getB() 
  {
    return pb->getB();
  }
};
Brian R. Bondy
+6  A: 

Solution 1: Use references if possible.

Solution 2: Just do the the null-pointer check and let the compiler take care about them. Removing redundant null-pointer checks is a standard optimization these days. They don't catch all but most of the redundancy.

Nils Pipenbrinck
+7  A: 

What do you expect to happen if B is null then in getB()? If it's not a valid state for your program, just assert(b != NULL). If it is a valid state, you need the check.

Some languages support contracts so you wouldn't need to manually write the checking code, but unfortunately C++ doesn't.

Michael
A: 

As Brian Bondy mentioned, a reference is one language-based way to do it. The only other option that I know of offhand to avoid null checks is the Null Object Pattern. That, of course, implies more work and control over how you're getting the B object.

Harper Shelby
A: 
// 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();
    }
};
Mykola Golubyev