I'm working on a situation where I'd like to have a certain base class that defines a static associative array and static functions that work with it, and then duplicate this functionality in classes that inherit from it, but with each child class having its own instance of the array. It looks like the child classes just inherit the parent's array, however, rather than creating their own static copy as I was hoping. The following is a super-simplified stripped down version of what I'd hoped to accomplish:
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);
}
Desired output:
-:[]
A:["a":"a1"]
B:["b":"b1"]
Actual output:
-:["a":"a1", "b":"b1"]
A:["a":"a1", "b":"b1"]
B:["a":"a1", "b":"b1"]
Is there a way around this without ditching inheritance and just duplicating the relevant code for each subclass? The actual code for assigning to the array I'm working with is more complex than just the attach function listed above, so I'd like to avoid having to duplicate it each time, or assign to .dict manually, if necessary. I'm wondering if there's a solution involving templates that might work, but I just can't seem to piece it together.
A static variable in a class is part of that class and only part of that class. There exists one instance of it in the entire program regardless of how many instances of that class have been created or how many classes have been derived from it. There is no inheritance of static member variables any more than there's inheritance of normal member variables. Derived classes have access to the base's variable if it's public or protected, but they don't get their own copy. Nothing is copied in a chain of derived classes. Member variables exist in the class that they're declared in with derived classes potentially having access to them, but derived classes don't get their own copy.
So, by putting dict in MyBase, you're created one of it for your entire program, regardless of what its derived classes do. If you want each of your derived classes to have its own copy, then they're each going to have to declare one of their own.
Now, you can minimize the code duplication via either a template mixin or a string mixin, but you're still going to have to mix it in to each derived class. For instance, you can do this
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With