Automatic method overriding in sub-classes

Tofu Ninja via Digitalmars-d digitalmars-d at puremagic.com
Tue Oct 27 16:15:37 PDT 2015


On Tuesday, 27 October 2015 at 22:23:15 UTC, bitwise wrote:
> [...]
> I just did a test for this. Using dmd's -H flag to generate 
> header files, the bodies of member functions are removed. If 
> you link a static library containing the compiled class though, 
> everything will work, and you can still inherit the class.
>
> [test.d]
> module test;
> import std.stdio;
> class Test { void foo() { writeln("test"); } }
> [/test.d]
>
> [main.d]
> module main;
> import test;
> import std.stdio;
> class Derived : Test {
>     override void foo() { writeln("derived"); }
> }
> void main() {
>     Derived d = new Derived();
>     d.foo(); // prints "derived"
> }
> [/main.d]
>
> With the above two files, I did this:
>
> dmd test.d -lib -H
> rm test.d   #make sure dmd can't find body of foo()
> dmd main.d test.a
> ./main
>
> The above will print "derived".
>
> I think dmd -H should definitely keep the definitions of auto 
> override functions when generating headers, but in theory,

-H also keeps the body of template functions so I would assume it 
would treat auto overrides the same.

> someone could remove them, and things could still work. If 
> someone received a static library and a D header file with 
> missing auto override function, they wouldn't be able to 
> inherit from the class, as if it were a sealed/final class. 
> This person, however, could work around the problem by 
> overriding the missing auto override function. I suppose this 
> is a good reason to adopt the semantics you are recommending, 
> where overriding an auto override function stops the automatic 
> behaviour, or else someone would have to override missing auto 
> override functions for every single level of inheritance after 
> the missing auto override. I suppose that if someone wanted to 
> resume the auto overrides, they could just override with 
> another auto override, and call the base class implementation 
> from their new override. With regards to the resuming of auto 
> overriding though, I'm wondering if what I am proposing is 
> possible in D. In C++, you can call any base method from 
> anywhere in a class hierarchy. In D however, it doesn't seem to 
> work.

I think you are correct, there is a scenario where one might want 
to provide a header to a class and not include the auto override 
body. An alternative solution could be that if you provide a 
header to a class and don't include the auto override body, then 
the auto override functionality is removed and the method is 
treated as a regular method from that point on(with the most 
recent version of the method being the one that is used). This 
would allow the class to still be inherited later on.

> [C++ ]
> struct A { virtual void foo() { printf("A\n"); } };
> struct B : public A { void foo() { printf("B\n"); } };
> struct C : public B { void foo() { A::foo(); } };
> int main() {
> 	C c;
> 	c.foo();   // prints "A"
> }
> [/C++]
>
> In D however, the following will cause a compiler error:
> "Error: identifier expected following '.', not 'super'"
>
> [D]
> class A { void foo() { writeln("A"); } }
> class B : A { override void foo() { writeln("B"); } }
> class C : B { override void foo() { super.super.foo(); } }
> void main() {
>     C c = new C();
>     c.foo();
> }
> [/D]
>
>     Bit

A.foo() or B.foo() seems to work instead of super.super.foo() or 
super.foo()


More information about the Digitalmars-d mailing list