Static data members cannot be inherited, so I see no chance to do this with ordinary subclassing / inheritance. You'll rather have to code this hierarchy, e.g. by introducing a map with the class names as keys.
I see one (ugly) "solution" by misusing templates, and it is so ugly that I want to share it with you :-).
It makes use of the fact that a template class, when parameterized/instantiated, yields a different class for different types. This also applies to their static data members:
template<typename T = char[100]>
class MyClass {
public:
static T val;
};
template<typename T>
T MyClass<T>::val = "";
class Derived1 : public MyClass<char[101]> {
};
class Derived2 : public MyClass<char[102]> {
};
int main() {
Derived1 c1;
Derived2 c2;
Derived2 c2_2;
strcpy(c1.val, "Herbert");
strcpy(c2.val, "Anton");
cout << c1.val << " " << c2.val << " " << c2_2.val << endl;
}
The output shows that Derived2-instances share a common value, whereas Derived1-instances have their own:
Herbert Anton Anton
The obvious drawback is that you have to introduce a different type (i.e. char[101], char[102],... for each subclass; otherwise it would not yield a different class and you would again share a common static variable. So
class Derived1 : public MyClass<char[101]> { ... }
class Derived2 : public MyClass<char[101]> { ... }
would yield output, such that even Derived1 and Derived2-instances share the same value for static data member val:
Anton Anton Anton
And that's why it is not only ugly but also unpractical.
Using "ordinary" inheritance, as mentioned in the introduction, will not help, since static data members are somehow equivalent to "global" variables within the namespace of the respective class. So they are not inherited, but you'll have to define such a variable for each subclass. And, as there is no inheritance on static data members, there is no dynamic binding on them:
class Base {
public:
static char v[100];
};
char Base::v[100];
class Derived_1 : public Base {
public:
static char v[100];
};
char Derived_1::v[100];
class Derived_2 : public Base {
public:
static char v[100];
};
char Derived_2::v[100];
int main() {
Derived_1 c1;
Derived_2 c2;
strcpy(Base::v, "Base");
strcpy(c1.v, "Herbert");
strcpy(c2.v, "Anton");
cout << c1.v << " " << c2.v << endl;
Base* b = &c2;
cout << b->v << endl;
return 0;
}
Output:
Herbert Anton
Base
So still not that what you want to achieve; And that's why I think that a map with the class names as keys remains a much better option.