[omniORB] Ambiguous inheritance error

David Riddoch djr@uk.research.att.com
Tue, 23 Feb 1999 18:09:29 +0000 (GMT)


Hi,

> Sorry for bothering you again, but I'm a little confused by your
> suggestion.  It sounds like you are suggesting an extra layer in
> which the members of C_i would call the appropriate A_i and B_i member
> functions.  That would add a lot of call overhead and I'm unclear how
> constructors and destructors for A_i and B_i would be handled.

Yes, this would involve an extra level of virtual function call. But next
to the cost of an entire call over the wire its pretty small.

> I have used similar IDL and header files with IONA's Orbix without a
> problem.  I was attempting to port the code to omniORB to test for
> interoperability between ORBs.  My actual code contains hundreds of
> functions so perhaps you can understand my lack of eagerness to add
> this extra layer.

Okay. The problem is essentially that the compiler is seeing 3 versions of
the dispatch() method - from _sk_C, _sk_A and _sk_B (and
_widenFromTheMostDerivedIntf similarly). It does not know which one should
be placed into C_i's virtual table, hence the error. We believe that the
C++ mapping does not intend that the implementation of a base class be
inherited in this way.

We've though a little more about this problem and have come up with two
more solutions. The best way to do it would be to use 'delegation-based
interface implementation' (see CORBA 20.34.4). We provide implementations
for A, B and C as follows:

class A_impl {
public:
  A_foo_1();
  A_foo_2();
};

class B_impl {
public:
  B_foo_1();
  B_foo_2();
};

class C_impl : public A_impl, public B_impl {
public:
  C_foo_1();
  C_foo_2();
};

We can then instantiate the objects like this:

A_impl* aimpl = new A_impl();
_tie_Test_A<A_impl,1>* aobj = new _tie_Test_A<A_impl,1>(aimpl);
aobj->_obj_is_ready(boa);

... B similarly ...

C_impl* cimpl = new C_impl();
_tie_Test_C<C_impl,1>* cobj = new _tie_Test_C<C_impl,1>(cimpl);
cobj->_obj_is_ready(boa);


If this looks like being too big a conversion for your purposes, I can
suggest a dirty hack! We need to dis-ambiguate the calls to dispatch() and
_widenFromTheMostDerivedIntf(), so we provide new versions in C_i:

class C_i : public virtual A_i,
            public virtual B_i,
            public virtual Test::_sk_C {
public:
  C_foo_1();
  C_foo_2();

  virtual CORBA::Boolean dispatch(GIOP_S& s,const char* op,
				  CORBA::Boolean response);
  virtual void* _widenFromTheMostDerivedIntf(const char* repoId,
				     CORBA::Boolean is_cxx_type_id);
};


CORBA::Boolean C_i::dispatch(GIOP_S& s,const char* op,
                             CORBA::Boolean response)
{
  return Test::_sk_C::dispatch(s, op, response);
}

void* C_i::_widenFromTheMostDerivedIntf(const char* repoId,
                                        CORBA::Boolean is_cxx_type_id)
{
  return Test::_sk_C::_widenFromTheMostDerivedIntf(repoId,is_cxx_type_id);
}


Hope one of these helps you!
David