2017-10-19 5 views
1

誰かが次のような行動を私に説明することはできますか?このように、基本クラスで"this T"の奇妙な振る舞い

abstract class Foo 
{ 
    string[] members; 

    final: 

    this(this T)(T child) 
    { 
     import std.conv : to; 

     foreach (member; __traits(derivedMembers, T)) 
     { 
      mixin("members ~= to!string(child." ~ member ~ ");\r\n"); 
     } 
    } 

    void printMembers() 
    { 
     writeln(members); 
    } 
} 

私はメンバーが渡された子型の値が移入されることを期待したいです。

しかし、動作は本当に奇妙です。

配列メンバーは無限に配置され、基本的にはプログラムがメモリ不足になります。

あなたはこれにミックスインを変更する場合:

mixin("if (members.length < 20) members ~= to!string(child." ~ member ~ ");\r\n"); 

、あなたは配列が読み込まれる方法を確認できるようになりますが、値は、コードがどのように動作するかをという点で意味がありません。

使用例:私のようなものを期待しているだろう

["1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar"] 
["100", "200", "300", "100", "200", "300", "100", "200", "300", "100", "200", "300", "100", "200", "300", "100", "200", "300", "100", "200", "f193.Baz", "f193.Baz", "f193.Baz", "f193.Baz", "f193.Baz", "f193.Baz"] 
["1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar", "f193.Bar"] 

:上記のコードは出力以下のように生成されます

class Bar : Foo 
{ 
    int baba; 
    int caca; 

    this() { baba = 1; caca = 2; super(this); } 
} 

class Baz : Foo 
{ 
    int foo; 
    int bar; 
    int baz; 

    this() { foo = 100; bar = 200; baz = 300; super(this); } 
} 

void main() 
{ 
    auto b = new Bar(); 
    auto a = new Baz(); 

    b.printMembers(); 
    a.printMembers(); 
    b.printMembers(); 
} 

["1", "2"] 
["100", "200", "300"] 
["1", "2"] 

まさにそれをしないのはなぜこのように振る舞う?それは私のバグのように見えますが、おそらく行動の理由がありますか?

答えて

1

コードを見ると、コンストラクタが再帰型と呼ばれるためです。

簡単な修正は以下の通りです:

static if (member != "__ctor") mixin("members ~= to!string(child." ~ member ~ ");\r\n");