对不起,如果我的问题太长而且技术性很好,但我认为其他人对此感兴趣非常重要
我正在寻找一种方法来清晰地分离出一些软件内部与其在c中的表示
我有一个通用参数类(以后存储在容器中),可以包含boost :: any类的任何类型的值
我有一个基本类(大概)这样的(当然还有更多的东西)
class Parameter { public: Parameter() template typename<T> T GetValue() const { return any_cast<T>( _value ); } template typename<T> void SetValue(const T& value) { _value = value; } string GetValueAsString() const = 0; void SetValueFromString(const string& str) const = 0; private: boost::any _value; }
派生类有两个级别:
第一级定义类型和转换为/从字符串(例如ParameterInt或ParameterString)
第二级定义行为和真正的创建者(例如从ParameterInt派生ParameterAnyInt和ParameterLimitedInt或从GenericString派生ParameterFilename)
根据实际类型,我想添加根据特定参数类型运行的外部函数或类,而不向基类添加虚拟方法,而不会进行奇怪的转换
例如,我想根据参数类型创建适当的gui控件:
Widget* CreateWidget(const Parameter& p)
当然,我不明白真正的参数类型,除非我使用RTTI或实现我的自我(使用枚举和开关案例),但这不是正确的OOP设计解决方案,你知道.
古典的解决方案是访客设计模式http://en.wikipedia.org/wiki/Visitor_pattern
这种模式的问题是,我必须提前知道哪些派生类型将被实现,所以(把所有的内容写在维基百科和我的代码中)我们会有一些:
struct Visitor { virtual void visit(ParameterLimitedInt& wheel) = 0; virtual void visit(ParameterAnyInt& engine) = 0; virtual void visit(ParameterFilename& body) = 0; };
是否有任何解决方案以任何其他方式获取此行为,而无需提前知道所有具体类型,而不导出原始访问者?
编辑:Dr. Pizza’s solution seems the closest to what I was thinking,但问题仍然是一样的,方法实际上依赖于dynamic_cast,我试图避免作为一种(即使是弱的)RTTI方法
也许最好是考虑一些解决方案,甚至不要引用访客模式,并清理我们的头脑.目的只是具有以下功能:
Widget* CreateWidget(const Parameter& p)
对每个“具体”参数的行为不同,而不会丢失其类型的信息