15.2 Inheritance-based Interface Implementation

In the inheritance-based interface implementation approach, the implementation classes are derived from a generated base class based on the OMG IDL interface definition. The generated base classes are known as skeleton classes, and the derived classes are known as implementation classes. Each operation of the interface has a corresponding virtual member function declared in the skeleton class. The generated skeleton class is partially opaque to the programmer, though it will contain a member function corresponding to each operation in the interface. The signature of the member function is identical to that of the generated client stub class.

To implement this interface using inheritance, a programmer must derive from this skeleton class and implement each of the operations in the OMG IDL interface. To allow portable implementations to multiple inheritances from both skeleton classes and implementation classes for other base interfaces without error or ambiguity, the Tobj_ServantBase class must be a virtual base class of the skeleton, and the PortableServer::ServantBase class must be a virtual base class of the Tobj_ServantBase class. The inheritance among the implementation class, the skeleton class, the Tobj_ServantBase class, and the PortableServer::ServantBase class must all be public virtual.

The implementation class or servant must only derive directly from a single generated skeleton class. Direct derivation from multiple skeleton classes could result in ambiguous errors due to multiple definitions of the _this() operation. This should not be a limitation, however, since CORBA objects have only a single most-derived interface. C++ servants that are intended to support multiple interface types can utilize the delegation-based interface implementation approach. See the following code snippet for an example of OMG IDL that uses interface inheritance.

// IDL
interface A
{
    short op1() ;
    void op2(in long val) ;
};

The following code snippet for an example of Interface Class A.

// C++
class A : public virtual CORBA::Object
{
    public:
       virtual CORBA::Short op1 ();
       virtual void op2 (CORBA::Long val);
};

On the server side, a skeleton class is generated. This class is partially opaque to the programmer, though it does contain a member function corresponding to each operation in the interface.

For the Portable Object Adapter (POA), the name of the skeleton class is formed by prepending the string “POA_” to the fully scoped name of the corresponding interface, and the class is directly derived from the servant base class Tobj_ServantBase. The C++ mapping for Tobj_ServantBase is as follows:

// C++
class Tobj_ServantBase
{
    public:
       virtual void activate_object(const char* stroid);
       virtual void deactivate_object (
           const char* stroid,
           TobjS::DeactivateReasonValue reason
    );
}

The activate_object() and deactivate_object() member functions are described in detail in the sections Tobj_ServantBase:: activate_object() and Tobj_ServantBase::_add_ref().

The skeleton class for interface A shown above would appear as shown in the following code snippet.

// C++
class POA_A : public Tobj_ServantBase
{
public:
   // ... server-side ORB-implementation-specific
   // goes here...
   virtual CORBA::Short op1 () = 0;
   virtual void op2 (CORBA::Long val) = 0;
   //...
};

If interface A were defined within a module rather than at global scope (for example, Mod::A), the name of its skeleton class would be POA_Mod::A. This helps to separate server application skeleton declarations and definitions from C++ code generated for the client.

To implement this interface using inheritance, you must derive from this skeleton class and implement each of the operations in the corresponding OMG IDL interface. An implementation class declaration for interface A would take the form shown in the following code snippet.

// C++
class A_impl : public POA_A
{
   public:
        CORBA::Short op1();
        void op2(CORBA::Long val);
        ...
};