Virtual methods on stack objects

vit vit at vit.vit
Thu May 12 10:30:14 UTC 2022


On Wednesday, 11 May 2022 at 20:53:21 UTC, Marvin Hannott wrote:
> On Wednesday, 11 May 2022 at 20:23:07 UTC, Ali Çehreli wrote:
>> On 5/11/22 13:06, Marvin Hannott wrote:
>>
>> > I appreciate the answer, don't much like the "solutions".
>>
>> Me neither. :)
>>
>> > It's not so much about copying
>>
>> Great!
>>
>> > scoped class objects should have value semantics.
>>
>> std.typecons.scoped does exactly that:
>>
>>   https://dlang.org/phobos/std_typecons.html#scoped
>>
>> import std.stdio;
>> import std.typecons;
>>
>> interface Animal {
>>   string sing();
>> }
>>
>> class Cat : Animal {
>>   this() {
>>     writeln("Hi!");
>>   }
>>
>>   ~this() {
>>     writeln("Bye!");
>>   }
>>
>>   string sing() {
>>     return "mew";
>>   }
>> }
>>
>> void foo(Animal animal) {
>>   writeln(animal.sing());
>> }
>>
>> void bar() {
>>   auto cat = scoped!Cat();
>>   foo(cat);
>> }
>>
>> void main() {
>>   bar();
>> }
>>
>> The output:
>>
>> Hi!
>> mew
>> Bye!
>>
>> Ali
>
> Yeah, but you can't return `Cat` 😉. And the documentation for 
> `scoped` says:
>>It's illegal to move a class instance even if you are sure 
>>there are no pointers to it. As such, it is illegal to move a 
>>scoped object.
>
> That's kinda very limiting.
>
> Anyway, I cooked up another idea based on your first 
> suggestions.
> ```D
> struct S
> {
>     static private interface I
>     {
>         int f(int i);
>     }
>
>     static private final class A : I
>     {
>         int f(int i) {return i;}
>     }
>
>     static private final class B : I
>     {
>         int f(int i) {return i+ 1;}
>     }
>
>     private I i;
>     private int d;
>
>     this(int d)
>     {
>         this.d = d;
>         if(d < 10)
>         {
>             i = scoped!A();
>         }else {
>             i = scoped!B();
>         }
>     }
>
>     int f() { return i.f(d);}
> }
> ```
> I mean, this is a super dumb example, but it kinda works. And I 
> think it could be made a lot less tedious with some mixin magic.

`scoped` is not necesary, try this:

```d
import std.typecons;

     struct S{
         static private interface I{
             int f(int i)const;
         }

         static private final class A : I{
             static immutable typeof(this) instance = new 
immutable typeof(this)();

             int f(int i)const {return i;}
         }

         static private final class B : I{
             static immutable typeof(this) instance = new 
immutable typeof(this)();

             int f(int i)const {return i+ 1;}
         }

         private immutable I i;
         private int d;

         this(int d){
             this.d = d;

             if(d < 10) i = A.instance;
             else i = B.instance;

         }

         int f() { return i.f(d);}
     }

     void main(){
     	import std.stdio;
     	S(1).f().writeln();  /// 1
     	S(100).f().writeln(); /// 101

}
```


More information about the Digitalmars-d-learn mailing list