3

私は、静的連想配列とそれと連携する静的関数を定義する特定の基本クラスを持ち、それを継承するクラスでこの機能を複製したいという状況に取り組んでいますが、各子クラスは配列の独自のインスタンス。子クラスは親の配列を継承しているように見えますが、私が望んでいたように独自の静的コピーを作成するのではありません。以下は、私が達成したいと思っていたものの非常に単純化された簡略版です。

class MyBase {
    static string[string] dict;
    static void attach(string key, string val) {
        dict[key] = val;
    }
}
class MySubA : MyBase {
    // various unique member variables
}
class MySubB : MyBase {
    // ...
}
void main() {
    MySubA.attach("a", "a1");
    MySubB.attach("b", "b1");
    writefln("-:%s", MyBase.dict);
    writefln("A:%s", MySubA.dict);
    writefln("B:%s", MySubB.dict);
}

必要な出力:

-:[]
A:["a":"a1"]
B:["b":"b1"]

実際の出力:

-:["a":"a1", "b":"b1"]
A:["a":"a1", "b":"b1"]
B:["a":"a1", "b":"b1"]

継承を破棄せずに、各サブクラスに関連するコードを複製するだけで、これを回避する方法はありますか?私が使用している配列に割り当てる実際のコードは、上記のアタッチ関数よりも複雑なので、毎回複製したり、必要に応じて手動で.dictに割り当てたりする必要はありません。うまくいくかもしれないテンプレートを含む解決策があるかどうか疑問に思っていますが、私はそれをつなぎ合わせることができないようです。

4

3 に答える 3

6

クラス内の静的変数は、そのクラスの一部であり、そのクラスの一部にすぎません。そのクラスのインスタンスがいくつ作成されたか、またはそこから派生したクラスがいくつあるかに関係なく、プログラム全体にそのインスタンスが 1 つ存在します。通常のメンバー変数の継承と同様に、静的メンバー変数の継承はありません。派生クラスは、パブリックまたは保護されている場合、ベースの変数にアクセスできますが、独自のコピーは取得しません。派生クラスのチェーンには何もコピーされません。メンバー変数は、派生クラスで宣言されているクラスに存在し、それらにアクセスできる可能性がありますが、派生クラスは独自のコピーを取得しません。

したがって、 を配置することdictMyBase、その派生クラスが何を行うかに関係なく、プログラム全体に対してその 1 つが作成されます。各派生クラスに独自のコピーを持たせたい場合は、それぞれ独自のコピーを宣言する必要があります。

これで、テンプレート mixin または文字列 mixin のいずれかを使用してコードの重複を最小限に抑えることができますが、それでも各派生クラスに混在させる必要があります。たとえば、これを行うことができます

import std.stdio;

mixin template Dict()
{
    static string[string] dict;
    static void attach(string key, string val)
    {
        dict[key] = val;
    }
}

class MyBase
{
    mixin Dict;
}

class MySubA : MyBase
{
    mixin Dict;
    // various unique member variables
}

class MySubB : MyBase
{
    mixin Dict;
    // ...
}

void main()
{
    MySubA.attach("a", "a1");
    MySubB.attach("b", "b1");
    writefln("-:%s", MyBase.dict);
    writefln("A:%s", MySubA.dict);
    writefln("B:%s", MySubB.dict);
}
于 2012-07-17T05:01:01.373 に答える
1

ああ、私はちょうど解決策に出くわしたように見えます。

class MyBase(T) {
    static string[string] dict;
    static void append(string key, string val) {
        dict[key] = val;
    }
}
class MySubA : MyBase!MySubA {
    // various unique member variables
}
class MySubB : MyBase!MySubB {
    // ...
}

まさに私が望んでいたことをします。簡単なエチケット検索に従って、自分の答えを投稿します。

于 2012-07-17T04:49:29.360 に答える
0

階層が必要ない場合:

import std.stdio;

mixin template Dict()
{
    static string[string] dict;
    static void attach(string key, string val)
    {
        dict[key] = val;
    }
}

class MySubA
{
    mixin Dict;
}

class MySubB
{
    mixin Dict;
}

void main()
{
    MySubA.attach("a", "a1");
    MySubB.attach("b", "b1");
    writefln("A:%s", MySubA.dict);
    writefln("B:%s", MySubB.dict);
}

このテンプレートの継承よりも優れたソリューションだと思います。

于 2012-07-23T07:26:59.520 に答える