Interfaces allow member definitions?

Steven Schveighoffer schveiguy at yahoo.com
Thu Jan 30 13:16:05 PST 2014


On Thu, 30 Jan 2014 15:57:06 -0500, Frustrated <c1514843 at drdrb.com> wrote:

> On Thursday, 30 January 2014 at 20:17:23 UTC, Steven
> Schveighoffer wrote:
>> 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.
>
> 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).

But what if it does need an object?

interface A
{
    void foo() { bar();} // need 'this' to call bar
    void bar();
}

> 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.

Keep in mind that an interface vtable exists as part of an object. The  
compiler knows this, and performs thunks when necessary.

> 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);

There is one function, but two vtables, one for A, and one for B. Both  
point at the same function.

> 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.

The difference is, now there is only one vtable, and one interface vtable  
inside B. A has no vtables. If you do this:

A a = new B;

a now points at the interface struct *inside B's object*. When you call  
a.foo, it does this:

1. It looks up in the interface vtable for A that's specific for B  
(accessed via the interface struct in the object itself) to get the  
function to call.
2. Included in the interface vtable struct is an offset to add so the  
'this' pointer actually points at the object itself instead of the  
interface struct.

> 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.

An interface instance and an object instance are two VERY different  
things, and are handled differently by the compiler.

-Steve


More information about the Digitalmars-d-learn mailing list