5770 Rate this article:

Beware of the Diamond Relationship: The danger of multiple class inheritances


When developing object-oriented IDL programs, a commonly used class is IDL_Object. This convenient superclass is used to provide the subclass that inherits it with IDL's _overload functionality. However, when multiple classes inherit IDL_Object, you can run into a problem if you try to write a class that inherits more than one superclasses that inherits IDL_Object.

Here are some class definition routines that illustrate the problem:

pro Superclass_A__define

  !null =
{Superclass_A, $
    inherits IDL_Object}

pro Superclass_B__define
  !null =
{Superclass_B, $
    inherits IDL_Object}


pro Subclass_S__Define
  !null =
{Subclass_S, $
    inherits Superclass_A, $
    inherits Superclass_B}

This can be called a diamond relationship because of the diamond that it makes in a class diagram.

Unfortunately, attempting to run this code would result in an error.

% Conflicting or duplicate structure tag definition: IDL_OBJECT_TOP.
% Execution halted at: SUBCLASS_A__DEFINE

Since there is more than one way to write code, there are a couple of alternatives to avoid this unwanted behavior resulting from the diamond relationship.

Only inherit base level classes (horizontal relationships)

If you want to avoid confusion as to what is inherited by inherited classes, then you could structure the classes so that you only inherit base classes, which are classes that don't inherit anything else. In this model, Superclass_A and Superclass_B would be the base classes. You wouldn't instantiate or call methods on them directly, but instead you would write new classes, Class_A and Class_B that would inherit both the base class and IDL_Object (also a base class). These new subclasses would then be the ones you would interact with.


Now Subclass_S would simply inherit the two base classes plus IDL_Object.


Use a linear inheritance structure (vertical relationships)

Another option is to use in inheritance structure that is completely linear. This means that each class inherits one and only one superclass.

This structure is simple and very safe in regards to avoiding conflicting superclasses. The drawback is that when you define Superclass_B to inherit Superclass_A, you are stating that B can be identified as A. In other words, Obj_Isa(B, 'Superclass_A') would return true. You may not necessarily want to associate the two together, in which case this would not be a suitable way to define your classes.

Other diamond relationships

In addition to IDL_Object, the diamond relationship can cause problems in many other cases. For instance, when the superclass at the top of the diamond contains a state or member variable, there are possible conflicts when the intermediate classes try to access or modify the single superclasse. In general, it's a relationship that you want to avoid.

These are not the only two solutions but just a couple of suggestions for how to build class relationships that avoid conflicts. If all else fails, draw a class diagram. After all, a picture is worth a thousand lines of code, right?