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:
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. 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?
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.
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.