0

To keep things as simple as I can I would like to construct a class with a static array. An array that is declared once and shared amongst all instances of the class throughout the lifetime of the program.

As an extension of the above question I was wondering if it was possible to form a hierarchy of inheritance such that the children will have different (static) arrays from their parents.

Finally if at all possible I would like to be able to declare these arrays within the header files for my classes.

Individually these tasks seem quite plausible but when combined I am absolutely stumped as to how I would code this, any help you can provide would be greatly appreciated, thanks in advance.

Edit

In header file:

class A {
public:
    static int[] arr;
    static int arrLength;
};

class B : A {
public:
    static int[] arr = {1, 2, 3}
    static int arrLength = 3;
};

Where A is just used as a root for a hierarchy and a certain level of polymorphism for other unrelated attributes and functions.

5
  • 1. Is it possible? Most likely yes. 2. Is it desirable? That's a whole another ball of wax. Commented Jan 12, 2018 at 22:48
  • 1
    @RSahu • I deleted my non-answer, your advice makes sense. Sorry about that. Commented Jan 12, 2018 at 23:05
  • I am not sure what you are asking. Could you provide some example code demonstrating what you are attempting to do? Commented Jan 12, 2018 at 23:05
  • @Eljay In regards to your first post I liked the shared pointer idea, but I'm not quite sure how I would initialize each instance to have the shared pointer already. Even more so I liked your example code, in fact it seems perfect! Unfortunately when I try to implement it myself it says that there is a syntax error at "static int[] arr;" saying that it is expecting another ";" character, which is strange to me, I'll try to provide a sample of what I am trying to do Commented Jan 12, 2018 at 23:11
  • There are a couple patterns that may be relevant: the Monostate Pattern, the Singleton Pattern, and the Pointer-to-Implementation (PImpl) pattern. A static shared pointer (std::shared_ptr) could combine the Monostate and PImpl. Maybe useful along with Stephan's accepted answer. :-) Commented Jan 13, 2018 at 15:10

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

wow talk about s unique approach, I'm impressed you could come up with this so quickly, it's elegant in it's ugliness. That is it's easy to see why it is impractical. On the other hand if static members cannot be inherited can I just redeclare them for their children (I also find it strange that children don't inherit their parents Static members)
That's a pretty awesome explanation thank you. So are all static members not inherited then? For instance what if I was to use a static vector<int> instead of an array, could I redefine it for each subclass?
On a different note, you mentioned the possibility of using maps, but how would i map each key (the class name) to multiple values (the arrays).
0

If you really need different arrays for derived types I suggest using a virtual generator function that returns a pointer to a static function-local array:

class Base
{
public:
    virtual Base * get_array()
    {
        static Base * array[]{ ... };
        return array;
    }
};
class Derived1 : public Base
{
public:
    Derived * get_array()
    {
        static Derived * array[]{ ... };
        return array;
    }
}

1 Comment

this seems like it would work, but I would like to try to avoid virtual functions if at all possible because I foresee a lot of overloading for a critical part of the system (that is for efficiency reasons I would like to try to avoid it)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.