Discussion:
[omniORB] Interface Inheritance
Vázquez Landa, David
2009-01-09 14:56:41 UTC
Permalink
Hi, I have a quick question.

Say I have an IDL such as:

Interface BaseInterface
{
void forty(int two);
};

Interface ChildInterface : BaseInterface
{
};

And then in the c++ implementation I want to have something like:

// --- some random class does:
Void test (BaseInterface_var baseInterface)
{
cout << "yay";
}

// --- I want to call this function with the child interface.

// For the sake of the argument:
ChildInterface_var childInterface = getChildInterface();

// This doesn't work
test(childInterface);


So, what would be the way to make this work? Should I use ChildInterface_ptr instead?
And if I use ChildInterface_ptr, do I have to explicitly destroy it once I'm finished using it? If so, how?

Hmm... This is kind of driving me nuts ??

Thanks :)
David.
Clarke Brunt
2009-01-09 16:11:59 UTC
Permalink
Someone else will have to confirm whether or not there are actually any
automatic conversions between the CORBA interface pointers and their base
classes - I can't remember without much studying.

Though actually, I see in the CORBA spec:

=====
OMG IDL interface inheritance does not require that the corresponding C++
classes
are related, though that is certainly one possible implementation. However,
if interface
B inherits from interface A, the following implicit widening operations for
B must be
supported by a compliant implementation:
. B_ptr to A_ptr
. B_ptr to Object_ptr
. B_var to A_ptr
. B_var to Object_ptr
=====

In general, it's not considered 'correct' to make the arguments to methods
be _var types. So your function test:

// --- some random class does:
Void test (BaseInterface_var baseInterface)
{
cout << "yay";
}

would be better as test (BaseInterface_ptr baseInterface) i.e. the same
signature it would have had if this was implementing a CORBA IDL method.

It's not 'wrong' to use _var - you can use whatever you like - but if you
use _var, there's a danger that someone will call the function with a _ptr,
which will likely go wrong - the _var will 'consume' the pointer, and
automatically release/delete it after the function call. And even if you
call it passing a _var, there's still a _var to _var copy operation going on
to pass the argument.

Whereas with the argument declared as _ptr, you can call it with either _ptr
or _var with no problems.

And from the extract from the spec above, your code will probably then work
- there's a conversion to _ptr but not to _var.
If I use ChildInterface_ptr, do I have to explicitly destroy it once I'm
finished using it? If so, how?

Best to leave your variable as _var, but just make the argument to the
method be _ptr.
But if you _really_ wanted to make things more difficult and use _ptr, the
you want CORBA::release(X_ptr) on it (which does the 'opposite' of
X::_duplicate(X_ptr)). You'd probably have to understand _duplicate to
implement your GetChildInterface function correctly.
Duncan Grisby
2009-01-09 17:50:59 UTC
Permalink
Post by Vázquez Landa, David
Hi, I have a quick question.
Interface BaseInterface
{
void forty(int two);
};
Interface ChildInterface : BaseInterface
{
};
Void test (BaseInterface_var baseInterface)
{
cout << "yay";
}
You should never ever use a _var type as a parameter type. If you do,
you will get into a great deal of memory management pain. You should
always use the _ptr type as the parameter type.
Post by Vázquez Landa, David
// --- I want to call this function with the child interface.
ChildInterface_var childInterface = getChildInterface();
// This doesn't work
test(childInterface);
So, what would be the way to make this work? Should I use
ChildInterface_ptr instead?
No, you should define the parameter to the test() function as
BaseInterface_ptr. Then the code you have here will work just fine.

Cheers,

Duncan.
--
-- Duncan Grisby --
-- ***@grisby.org --
-- http://www.grisby.org --
Loading...