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

类中的静态变量是该类的一部分,并且只是该类的一部分。无论创建了多少个该类的实例或从它派生了多少类,整个程序中都存在它的一个实例。没有静态成员变量的继承,就像普通成员变量的继承一样。如果基类变量是公共的或受保护的,派生类可以访问它,但它们没有自己的副本。派生类链中没有任何内容被复制。成员变量存在于声明它们的类中,派生类可能可以访问它们,但派生类没有自己的副本。

因此,通过放入dictMyBase您为整个程序创建了其中一个,而不管它的派生类做什么。如果您希望每个派生类都有自己的副本,那么它们每个都必须声明自己的一个。

现在,您可以通过模板 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 回答