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