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