假设我有基类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
。每个派生类都有自己的一组有效密钥
我的目标是:
k_valid_keys
成为Validator
的成员。不需要将它添加到每个派生类中,特别是当它们有多种类型时。k_valid_keys
static
。假设我有Validator
(及其派生类)的多个实例,k_valid_keys
的初始化很昂贵。如何以多态方式初始化static
成员?好吧,我知道它无法完成(如果我错了,请更正)。
所以假设它无法完成,对这个问题有更好的设计想法吗?
答案 0 :(得分:2)
由于k_valid_keys
在static
处声明为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
类。