On Wednesday, 12 October 2016 at 02:33:20 UTC, lobo wrote:
On Wednesday, 12 October 2016 at 02:18:47 UTC, TheFlyingFiddle
wrote:
On Wednesday, 12 October 2016 at 01:22:04 UTC, lobo wrote:
Hi,
I'm coming from C++ and wondered if the pattern below has an
equivalent in D using structs. I could just use classes and
leave it up to the caller to use scoped! as well but I'm not
sure how that will play out when others start using my lib.
Thanks,
lobo
module A;
class Base1 {
int ival = 42;
}
class Base2 {
int ival = 84;
}
module B;
class S(ABase) : ABase {
string sval = "hello";
}
module C;
import A;
import B;
void main() {
auto s= scoped!(S!Base1); // scoped!(S!Base2)
}
You could use "alias this" to simulate that type of
inheritence.
module A;
struct Base1
{
int ival = 42;
}
module B;
struct Base2
{
int ival = 84;
}
module C;
import A, B;
struct S(Base) if(is(Base == struct))
{
Base base;
alias base this;
string sval = "Hello ";
}
void foo(ref ABase base)
{
base.ival = 32;
}
void main()
{
S!Base1 a;
S!Base2 b;
writeln(a.sval, a.ival);
writeln(b.sval, b.ival);
foo(a);
writeln(a.sval, a.ival);
}
This approach works nicely although it feels clumsy but that's
probably just because I'm so used to C++. It also handles
private members as I'd expect, i.e. they're not accessible
outside module scope through the alias struct instance, but
there is no protected. Protected appears to behave the same way
as private.
I think I can live with that because I usually try to avoid
protected anyway.
Thanks,
lobo
Note that alias this is not inheritance, it's subtyping. What
happens when doing:
struct P { int val = 42; }
struct S { P p; alias p this; }
assert(S().val == 42);
is that S tries to find “ this.val ”. First it looks in its scope
without success. Then it uses the alias to transform “ this.val ”
into “ p.val ”, but the type S isn't linked to the type P. When
using attributes of p you are really dealing with a real object
of type P. It also means that implicit conversion of S in P will
just copy the p member:
struct P {
int val = 42;
}
struct S {
P p;
alias p this;
int val = 1234;
}
void main(string[] args) {
P p = S();
assert(p.val == 42);
}
Assert this is a great feature but it has to be well understood.