Alternative to Interfaces

1001Days onek1days at anon.anon
Fri Jan 18 01:58:47 UTC 2019


On Friday, 18 January 2019 at 01:00:33 UTC, H. S. Teoh wrote:
>Maybe you could help us answer your question better by 
>explaining a bit more what you're trying to achieve.  Generally, 
>if you want to use an interface, that usually means you want (1) 
>runtime polymorphism, i.e., the ability to swap one concrete 
>implementation for another at runtime, and (2) pass around 
>possibly different concrete objects to code that expects objects 
>of a single type (the interface type).
I do apologize for my vagueness. In hindsight, it was quite a 
poor way to request for help. Anyway, for my current use case, 
the latter's functionality is what I am attempting to replicate.
>If the reason you're using structs is just to avoid the GC, then 
>you should look up emplace() in the docs.  It *is* possible to 
>use classes without using the GC.  Just in case you didn't know.
Thank you for informing me of this. I didn't know. So from a 
cursory glance it would seem that I would, omitting details, make 
a wrapper function that combines an allocator (e.g. malloc) and 
emplace.
>(Though you should also keep in mind the possible drawbacks of 
>template bloat -- which may cause more instruction cache misses 
>by making your code larger than it could have been.)
Yes, this is something I worried about too.
>My personal tendency is to start with structs and compile-time 
>introspection as an initial stab, but depending on what might be 
>needed, I may use some classes / interfaces.  The two can be 
>combined to some extent -- e.g., a template function can take 
>both structs with compile-time introspection and also classes 
>that allow runtime polymorphism.  A template function 
>instantiated with a class type will be able to accept different 
>concrete objects at runtime (as long as they are subclasses of 
>that type).  However, it will only be able to "see" the static 
>info of the class it was instantiated with, not any additional 
>features of derived classes that it may receive at runtime, 
>since there will be no runtime introspection.
Initially, I was going to use Classes when I needed to use 
Interfaces and use Structs for everything else, but I decided 
against that because I was worried it would make the program's 
structure "inconsistent," for the lack of a better word, and 
again the GC.
>Though AFAIK, delegates probably still need heap allocation and 
>depend on the GC, esp. if you have closures over local 
>variables.  There may be some cases where the compiler will 
>elide this, e.g., if you have a function literal passed via an 
>alias that does not escape the caller's scope.  OTOH, you might 
>be able to get around needing the GC if you put your delegates 
>in an emplace()'d class as methods, and take their address 
>(which produces a delegate).  Just make sure your class doesn't 
>go out of scope while the resulting delegates are still around. 
>Keep in mind that in this case, you will not be able to have 
>closure over local variables (delegates can only have 1 context 
>pointer, and in this case it's already used up by the `this` 
>reference) and will have to store any such contextual 
>information inside the class itself.
With regards to the emplaced class, this is interesting. My main 
use for the delegate was in achieving one of the effects of 
interfaces for Structs, so I don't think I'll be using them as 
much. I'll have to pay close attention to the profiler in any 
case.

With the information you gave me, I think I'll try Class & 
emplace as I really don't want to attempt replicate existing 
functionality--especially so considering my experience level.

With thanks,
1001Days


More information about the Digitalmars-d-learn mailing list