Interfaces allow member definitions?

Frustrated c1514843 at drdrb.com
Thu Jan 30 12:57:06 PST 2014


On Thursday, 30 January 2014 at 20:17:23 UTC, Steven
Schveighoffer wrote:
> On Thu, 30 Jan 2014 14:58:42 -0500, Frustrated 
> <c1514843 at drdrb.com> wrote:
>
>> On Thursday, 30 January 2014 at 17:11:24 UTC, Steven
>> Schveighoffer wrote:
>>> On Thu, 30 Jan 2014 11:58:15 -0500, Frustrated 
>>> <c1514843 at drdrb.com> wrote:
>>>
>>>
>>>> Essentially what it boils down to is treating interfaces like
>>>> classes that have no fields). To avoid the diamond problem 
>>>> simply
>>>> always choose the method that is not from the 
>>>> interface(since it
>>>> is "default"), which is done naturally with the vtable.
>>>
>>> It's simpler than that. A function is a block of code. A 
>>> vtable entry points to a block of code. Just point the vtable 
>>> entry at the block of code that is the default implementation.
>>>
>>> -Steve
>>
>> But what if you want to provide some default behavior? We are 
>> not
>> dealing with abstract classes here.
>>
>> Since there is currently no way to do what I am saying no
>> "solution" will be adequate unless it fulfills the behavior.
>>
>> (again, it's not like we can't accomplish basically the same
>> thing, the point is mainly about simplification)
>>
>> The question was about if there was any innate reason why this
>> type of behavior couldn't be accomplish using the vtable. I'm
>> assuming there is none and it could easily be done? (the 
>> compiler
>> just has to reserve the space and setup the pointers to the
>> functions?)
>
> The interface defines the vtable, the class contains a value 
> for that vtable.
>
> If you imagine an interface vtable like this:
>
> interface A
> {
>    void foo();
> }
>
> =>
>
> struct A_vtbl
> {
>    void function() foo;
> }
>
> Note the default value is NULL.
>
> When you create a class that inherits, it's class info contains 
> an A_vtbl:
>
> class B : A
> {
>    void foo() {writeln("hi";}
> }
>
> =>
>
> struct B_typeinfo
> {
>    A_vtbl a_interface = {&B.foo};
> }
>
> And when you call foo on an instance of A, it uses the vtable, 
> knowing that the layout is A_vtbl.
>
> (this is simplistic, the real thing is more complex to explain, 
> it's somewhere on the docs).
>
> What I'm saying is, if you give a default to the function foo, 
> then our straw-man A_vtbl looks like this:
>
> struct A_vtbl
> {
>    void function() foo = A.default_foo;
> }
>
> And when you create B_typeinfo, if you haven't defined foo, it 
> just points at that default foo (of course, you have to fill in 
> B.foo, and for that, you actually have to do a thunk to convert 
> to the interface I think, but this is not hard).
>
> But it's important to note that A does not define an instance 
> of A_vtbl, just the layout! You still need a concrete class to 
> get a vtable instance to point at.
>
> -Steve

But what I think you are failing to realize is that regardless
that foo is defined in an interface, since foo does not use this,
it does not depend on the object, so it does not need an
object(for all practical purposes it is a static function but of
course must take an object as the first parameter so it is
compatible as a member function).

Also, regardless that it is an interface, doesn't mean it can't
have a concrete vtable to work with.

The fact is that a vtable is more complex because it has the
ability to call functions defined in a base class. In this case a
"base" interface.

Just because something doesn't exist there now doesn't mean it
can't exist.

Answer me this

class A { void foo() { } }
class B : A {  }

B b = new B;
b.foo();

are you telling me there are actually two foo functions? or does
b actually call A's foo passing it the object b e.g., the call
made is actually foo(b);


If so, then what if A is an interface? (by interface, I am
talking about one that has a vtable created for it's members)


interface A { void foo() { } }
class B : A {  }

B b = new B;
b.foo();

Whats the difference? Absolutely nothing but your interpretation
of what an interface is.

This is all about semantics. If you want to think of an interface
as some idealized abstract compile time object that doesn't exist
at run time and has no vtable then so be it. But that doesn't
mean it has to be and I'm just saying it is limiting.

Obviously the difference between the two above is that the
compiler does not allow multiple inheritance w.r.t, to classes,
and does not allow fields in interfaces, etc... but these rules
can still be enforced on a class THAT HAS A VTABLE.

I think you still keep trying to fit the square peg in the round
hole. I'm not talking about what the compiler does... we know the
above code as I intend it does not work.


More information about the Digitalmars-d-learn mailing list