如何多态初始化`static`成员

时间:2014-03-26 09:44:23

标签: c++ polymorphism static-members

假设我有基类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;
};

现在假设我需要扩展类Validator。每个派生类都有自己的一组有效密钥 我的目标是:

  1. k_valid_keys成为Validator的成员。不需要将它添加到每个派生类中,特别是当它们有多种类型时。
  2. 保持k_valid_keys static。假设我有Validator(及其派生类)的多个实例,k_valid_keys的初始化很昂贵。
  3. 如何以多态方式初始化static成员?好吧,我知道它无法完成(如果我错了,请更正)。

    所以假设它无法完成,对这个问题有更好的设计想法吗?

3 个答案:

答案 0 :(得分:2)

由于k_valid_keysstatic处声明为Validator,因此Validator中的所有派生类将共享k_valid_keys的同一个实例。就是这样,您将无法在程序中同时拥有Validator子类的多个实例,否则Validator子类的不同实例将向同一结构添加元素

也就是说,类上的静态成员变量只是整个程序的全局变量。

如果你有两个或更多的Validator子节,但是你保证只有一个实例,你只需在子类构造函数上初始化k_valid_keys

答案 1 :(得分:1)

您可以执行以下操作:将一组键映射为静态成员,使用映射映射std :: type_index来设置键(或者,如果您不能使用C ++ 11,则std :: type_info *) 。在每个派生类中都有一个虚函数,它返回一个类的valid_keys集,基类中的validate函数应该与typeid实际对象的type_info一起得到,检查它是否已经有地图中的键 - 如果没有,则调用虚拟函数返回集,并将该条目添加到地图中。

答案 2 :(得分:0)

k_valid_keys类的构造函数中传递对Validator的引用,并初始化成员引用。您将跳过多个Validator课程的构建,但您必须管理其生命周期。

如果你想要或不想,你可以为每个继承的类型提供一个。

使用按类型或密钥访问的k_valid_keys寄存器也可以使用。当然,您需要将对此寄存器的引用传递给Validator类。