How to do "inheritance" in D structs
cym13 via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Wed Oct 12 02:30:48 PDT 2016
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.
More information about the Digitalmars-d-learn
mailing list