Inheritance D:继承静态变量,按类区分?

Inheritance D:继承静态变量,按类区分?,inheritance,static-methods,static-members,d,Inheritance,Static Methods,Static Members,D,我正在处理这样一种情况:我希望有一个特定的基类,它定义一个静态关联数组和使用它的静态函数,然后在继承它的类中复制这个功能,但是每个子类都有自己的数组实例。但是,看起来子类只是继承父类的数组,而不是像我希望的那样创建自己的静态副本。以下是我希望实现的超级简化精简版: class MyBase { static string[string] dict; static void attach(string key, string val) { dict[key] = v

我正在处理这样一种情况:我希望有一个特定的基类,它定义一个静态关联数组和使用它的静态函数,然后在继承它的类中复制这个功能,但是每个子类都有自己的数组实例。但是,看起来子类只是继承父类的数组,而不是像我希望的那样创建自己的静态副本。以下是我希望实现的超级简化精简版:

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"]

有没有办法不放弃继承,只为每个子类复制相关代码?分配给我正在使用的数组的实际代码比上面列出的attach函数更复杂,因此我希望避免每次都要复制它,或者在必要时手动分配给.dict。我想知道是否有一个涉及模板的解决方案可以工作,但我似乎无法将其组合起来。

啊,看起来我刚刚偶然发现了这个解决方案

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 {
    // ...
}

这正是我想要的。根据快速礼仪搜索发布自己的答案。

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

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

现在,您可以通过模板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);
}

如果不需要层次结构:

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);
}

我认为这是一个比模板继承更好的解决方案。

正如您所知,
MySubA
MySubB
不会以这种方式共享相同的基类。它们位于完全独立的类层次结构中,因为
MyBase!MySubA和MyBase!MySubB
是不同的类。同一模板的不同安装是完全独立的实体,彼此之间没有任何关系。如果实际上不需要类层次结构(并且仅用于提供dict实现),那么我会说模板混合是一种方法。+1肯定是@ccjuju,如果您只是使用继承来避免一点重复,请不要使用泛型。另一方面,如果这些类确实表示对象层次结构,那么您发布的解决方案不会满足您的要求。