[Up: C++ mapping]
[Previous: Unions] [Next: Modules]

#
Interface inheritance

The CORBA standard prescribes that IDL-interfaces need to be mapped to C++ classes for the C++ language binding. The question arises, how things are handled when interface inheritance is used. MICO offers two alternatives for implementing the skeletons when using interface inheritance. Consider the following IDL definitions:

      interface Base {
        void op1();
      };

      interface Derived : Base {
        void op2();
      };

`Base` is an interface and serves as a base for interface `Derived`. This means that all declarations in `Base` are inherited to `Derived`. As we have seen before, the `idl` tool creates stub- and skeleton-classes for each interface. The operations map to pure virtual functions which have to be implemented by the programmer. For the interface `Base` this is straight forward:

      class Base_impl : virtual public Base_skel
      {
      public:
        Base_impl()
        {
        };
        void op1()
        {
          cout << "Base::op1()" << endl;
        };
      };

The skeleton for `Derived` allows two different possible ways to implement the skeleton. The difference between the two is, whether the implementation of `Derived` inherits the implementation of `Base` or not. Let's take a look on how this translates to lines of code. Here is the first alternative:

      class Derived_impl :
        virtual public Base_impl,
        virtual public Derived_skel
      {
      public:
        Derived_impl()
        {
        };
        void op2()
        {
          cout << "Derived::op2()" << endl;
        };
      };

In the code fragment above, the implementation of `Derived` inherits the implementation of `Base`. Note that `Derived_impl` inherits from `Base_impl` and therefore needs only to implement `op2()` since `op1()` is already implemented in `Base_impl`.

Important note: when implementing a class `X_impl` that inherits from multiple base classes you have to ensure that the `X_skel` constructor is the last one that is called. This can be accomplished by making `X_skel` the rightmost entry in the inheritance list:

      class X_impl : ..., virtual public X_skel {
        ...
      };

Now comes the second alternative (note that the skeleton classes are still the same; there is no particular switch with the `idl` tool where you have to decide between the two alternatives):

      class Derived_impl :
        virtual public Base_skel,
        virtual public Derived_skel
      {
      public:
        Derived_impl()
        {
        };
        void op1()
        {
          cout << "Derived::op1()" << endl;
        };
        void op2()
        {
          cout << "Derived::op2()" << endl;
        };
      };

You should notice two things: first of all `Derived_impl` is no longer derived from `Base_impl` but rather from `Base_skel`. For this reason the class `Derived_impl` needs to implement the operation `op2()` itself. Figure 5.2 shows the inheritance hierarchy for the classes generated by the IDL-compiler and their relationship to the classes contained in the MICO library. Compare this with figure 3.3 on page . This example can also be found in the directory `mico/test/idl/15`.

Figure 5.2: C++ class hierarchy for interface inheritance.

[Previous: Unions] [Next: Modules]
[Up: C++ mapping]