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