-betterC and extern(C++) classes
Moritz Maxeiner via Digitalmars-d
digitalmars-d at puremagic.com
Sun Sep 10 09:48:06 PDT 2017
On Sunday, 10 September 2017 at 15:12:12 UTC, Yuxuan Shui wrote:
> On Sunday, 10 September 2017 at 14:42:42 UTC, Moritz Maxeiner
> wrote:
>> On Sunday, 10 September 2017 at 14:04:20 UTC, rikki cattermole
>> wrote:
>>> On 10/09/2017 2:19 PM, Moritz Maxeiner wrote:
>>>> If TypeInfo for extern(C++) classes is removed, couldn't
>>>> final extern(C++) classes without base class and which don't
>>>> implement any interfaces omit the vtable so that the
>>>> following assert holds:
>>>>
>>>> ---
>>>> final extern(C++) class Foo {}
>>>> static assert (__traits(classInstanceSize, Foo) == 0LU);
>>>> ---
>>>>
>>>> The reason I ask is that fairly often I have an abstraction
>>>> that's better suited as a reference type than a value type,
>>>> but doesn't need any runtime polymorphy (or the monitor
>>>> standard classes have). Structs + pointers are the only way
>>>> I know of to avoid the (in this special case) unneeded
>>>> vtable overhead, but it always ends up looking worse to read.
>>>
>>> We can do it for any class if its final.
>>
>> Even final classes can always inherit (potentially already
>> overridden) virtual methods from their parent classes and
>> since all normal D classes inherit from core.object : Object
>> [1], which defines virtual methods (`toString`, `toHash`,
>> `opCmp, and `opEquals`), I don't see how this can be true.
>
> With a final class reference, we always know what function to
> call at compile time (since it can't be inherited). Therefore
> we don't need a vtable.
---
class Base
{
string name()
{
return "Base";
}
}
class ChildA : Base
{
override string name()
{
return "ChildA";
}
}
final class ChildB : Base
{
override string name()
{
return "ChildB";
}
}
void foo(Base b)
{
import std.stdio;
b.name.writeln;
}
void main(string[] args)
{
Base b;
if (args.length > 1) b = new ChildA;
else b = new ChildB;
b.foo();
}
---
It is not known at compile time which class `foo`'s parameter `b`
will actually be an instance of (Base, ChildA, or ChildB), so
static dispatch is not possible; it requires dynamic dispatch.
Since dynamic dispatch for classes is done in D via vtables,
ChildB needs a vtable.
More information about the Digitalmars-d
mailing list