Multiple inheritance and covariant return types.
Regan Heath
regan at netmail.co.nz
Thu Aug 9 09:06:37 PDT 2007
Regan Heath wrote:
> BCS wrote:
>> Reply to Frank,
>>
>>> Hi,
>>>
>>> I have another question on multiple inheritance. The following code
>>> does not work (tested with DMD 1.020 and 2.003)
>>>
>>> ---
>>> interface A {}
>>> interface B {}
>>>
>>> interface AB: A, B {}
>>>
>>> abstract class X {
>>> abstract A func();
>>> }
>>> interface Y {
>>> B func();
>>> }
>>> class XY: X, Y {
>>> AB func() { return null; }
>>> }
>>> ---
>>> The compiler complains about the line 'AB func() { return null; }':
>>> t.d(38): function t.XY.func incompatible covariant types A() and B()
>>>
>>> but I think it should work, because AB is both, an A and a B, so the
>>> return type is covariant with both overridden methods. In fact, the
>>> example works fine, if X is an interface instead of an abstract class.
>>>
>>> Is this a bug or is it my mistake?
>>>
>>> Thanks,
>>> Frank
>>
>> The issues is that casting from a class that implements A, B and AB to
>> each of these results in a slightly different result.
>>
>> IIRC when a class is cast to an interface, what you get is a pointer
>> to a v-table inside of the class (not the normal one). However because
>> AB inherits from A and B, you end up getting two different v-tables.
>> So returning an AB interface instance would give you something that is
>> an AB and might be an A or B but not both. (This is all at the binary
>> level of course)
>
> So, AB isn't "A or B" but "A and B" and the OP really wants some way to
> say "A or B".
>
> Specifically 'func' needs to return either A or B based on usage, eg.
>
> A a = func(); //returns A
> B b = func(); //returns B
>
> Unfortunately you can't overload based on return type or this might have
> worked:
>
> interface A {}
> interface B {}
>
> interface AB: A, B {}
>
> abstract class X {
> abstract A func();
> }
>
> interface Y {
> B func();
> }
>
> template TFunc(T) { T func() { return null; } }
>
> class XY: X, Y {
> mixin TFunc!(A);
> mixin TFunc!(B);
> }
>
> void main()
> {
> XY xy = new XY;
> A a = xy.func();
> B b = xy.func();
> }
Actually, ignore me I think I must have the wrong end of the stick.
Regan
More information about the Digitalmars-d-learn
mailing list