Automatic method overriding in sub-classes

bitwise via Digitalmars-d digitalmars-d at puremagic.com
Tue Oct 27 15:23:14 PDT 2015


On Tuesday, 27 October 2015 at 20:05:17 UTC, Tofu Ninja wrote:
> On Tuesday, 27 October 2015 at 14:47:03 UTC, bitwise wrote:
>> [...]
>
> Is there ever a chance the auto override definition would not 
> be available, I think the class chain all the way up to Object 
> always needs to be available at compile time to compile a 
> class, so I don't see any time an auto override definition 
> would be missing.
>
> I do like the idea of manually overriding as well if needed, 
> but with slightly different semantics than what you said.
>
> -Manually overriding an auto override with a regular method 
> would simply work and would stop the automatic overriding from 
> that class on.
>
> -Overriding an auto override with another auto override would 
> cause the new auto override to be used from that class on.
>
> -Final could still be used to stop all overriding from that 
> class on.
>
> You could even override a normal method with an auto override 
> and have no problems.

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

[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




More information about the Digitalmars-d mailing list