Question

Say I have base class Validator.

class Validator
{
public:
  void validate(const string& str)
  {
    if( k_valid_keys.find(str) == k_valid_keys.end() ) 
      throw exception();
  }
private:
  const static std::set<string> k_valid_keys;
};

Now assume I need to extend class Validator. Each derived class will have its own set of valid keys.
My goal is:

  1. keep k_valid_keys a member of Validator. No need to add it to each derived classes especially when there are more than a few types of those.
  2. keep k_valid_keys static. Assume I have multiple instances of Validator (and its derived classed) and initialization of k_valid_keys is expensive.

How can I initialize static member polymorphically? well, I know that it can't be done (please correct if I'm wrong).

So Assuming it can't be done, any idea of a better design for this problem?

Was it helpful?

Solution

Since k_valid_keys is static declared at Validator, all the derived classes from Validator will share the same instance of k_valid_keys. That's it, you will not be able to have more than one instance of a subclass of Validator at the same time in your program, else your different instances of subclases of Validator will add elements to the same structure.

That's is, a static member variable on a class is just a global variable of your entire program.

If you have two or more subclases of Validator but you guarantee that you are going to have only just one instance, you just initialize k_valid_keys on the subclass constructor.

OTHER TIPS

You can do the following: instead of one set of the keys as static member, use a map mapping std::type_index to set of keys (or, if you cannot use C++11, std::type_info*). In each of your derived classes have a virtual function which returns the set of valid_keys for a class, and the validate function in the base class should get with typeid the type_info of the actual object, check if it already has the keys in the map - if not, the virtual function return the set is called, and the entry is added to the map.

Pass a reference to k_valid_keys in the constructor of your Validator classes and initialize a member reference. You'll skip construction for multiple Validator classes but you'll have to manage its lifetime.

You can then have one per inherited type if you want or not as well.

Using a register of k_valid_keys that is accessed by type or key could also work. Of course you would need to pass a reference to this register to your Validator classes.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top