Avoiding the Diamond of Death

The final problem with our inheritance approach involves the situation where we take code reuse to the extreme. In our hierarchy, we have SuperRaider, which is very fast, weak, and shoots little bullets. We also have SuperBomber, which is slow, strong, and shoots big bombs. Someday, a clever designer will want to create SuperBomberRaider that is very fast, strong, and shoots both little bullets and big bombs. Here is our partial tree:

Figure 3.5 - Example of the Diamond of Death

This, of course, is the Diamond of Death (or Dreaded Diamond of Death), so named because the inheritance tree forms a diamond. The problem is that our SuperBomberRaider inherits from both the SuperBomber and SuperRaider. Those two classes each inherit from the Enemy, Unit, and object. That means SuperBomberRaider will have two copies of m_pos, m_scale, m_rotation, and every other member of object, Unit, and Enemy.

There will also be two copies of any functions that are contained in the Object, Unit, and Enemy. This means we need to specify which version of the functions we wish to use. This might sound good, since we get behavior from both classes, but remember that the individual base class function will only modify their version of variables. After calling SuperRaider::Update and SuperBomber::Update, we now need to figure out what version of m_pos (and m_scale and m_rotation) we want to use when we draw our object.

C++ has ways of solving this problem, but most programmers agree that the solution makes things more complicated to understand and more difficult to use. The rule of thumb is that we should just avoid using multiple inheritance. We have seen some of the problems that it can cause and we haven't even talked about bugs related to using new and delete in a situation like this.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.120.187