我正在处理一种情况,我希望有一个定义静态关联数组的基类和使用它的静态函数,然后在从它继承的类中复制此功能,但每个子类具有自己的数组实例。看起来子类只是继承了父类的数组,而不是像我希望的那样创建自己的静态副本。以下是我希望完成的超简化精简版:
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。我想知道是否有一个可能有效的模板解决方案,但我似乎无法将它拼凑在一起。
答案 0 :(得分:6)
类中的静态变量是该类的一部分,只是该类的一部分。无论已创建该类的实例数或从中派生了多少个类,整个程序中都存在一个实例。静态成员变量的继承不再是普通成员变量的继承。派生类可以访问基础变量(如果它是公共的或受保护的),但它们不会获得自己的副本。 Nothing 被复制到派生类链中。成员变量存在于它们声明的类中,派生类可能有权访问它们,但派生类不会获得它们自己的副本。
因此,通过将dict
放在MyBase
中,您可以为整个程序创建其中一个,无论其派生类是什么。如果您希望每个派生类都有自己的副本,那么他们每个人都必须声明自己的副本。
现在,您可以通过模板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);
}
答案 1 :(得分: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 {
// ...
}
完全符合我的要求。根据快速礼节搜索发布自己的答案。
答案 2 :(得分: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);
}
我认为这是比这个模板继承更好的解决方案。