c – 更通用的访问者模式

对不起,如果我的问题太长而且技术性很好,但我认为其他人对此感兴趣非常重要

我正在寻找一种方法来清晰地分离出一些软件内部与其在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)

对每个“具体”参数的行为不同,而不会丢失其类型的信息

解决方法

对于 Vistor的一般实现,我建议 Loki Visitor,Loki library的一部分.

相关文章

对象的传值与返回说起函数,就不免要谈谈函数的参数和返回值...
从实现装饰者模式中思考C++指针和引用的选择最近在看...
关于vtordisp知多少?我相信不少人看到这篇文章,多半是来自...
那些陌生的C++关键字学过程序语言的人相信对关键字并...
命令行下的树形打印最近在处理代码分析问题时,需要将代码的...
虚函数与虚继承寻踪封装、继承、多态是面向对象语言的三大特...