C++ 更通用的访问者模式
我很抱歉,如果我的问题是这么长和技术,但我认为它是如此重要,其他人会对此感兴趣 我在寻找一种方法,将一些软件的内部结构与它们在c语言中的表示清楚地分开++ 我有一个泛型参数类(稍后存储在容器中),它可以包含boost::any类中的任何类型的值 我有一个这样的基类(大致上)(当然还有更多的东西) 当然,除非我使用RTTI或自己实现它(使用enum和switch case),否则我无法从中理解真正的参数类型,但您知道,这不是正确的OOP设计解决方案 经典的解决方案是访问者设计模式 这种模式的问题是,我必须提前知道将实现哪些派生类型,因此(将wikipedia中编写的内容和我的代码放在一起)我们将有:C++ 更通用的访问者模式,c++,design-patterns,visitors,C++,Design Patterns,Visitors,我很抱歉,如果我的问题是这么长和技术,但我认为它是如此重要,其他人会对此感兴趣 我在寻找一种方法,将一些软件的内部结构与它们在c语言中的表示清楚地分开++ 我有一个泛型参数类(稍后存储在容器中),它可以包含boost::any类中的任何类型的值 我有一个这样的基类(大致上)(当然还有更多的东西) 当然,除非我使用RTTI或自己实现它(使用enum和switch case),否则我无法从中理解真正的参数类型,但您知道,这不是正确的OOP设计解决方案 经典的解决方案是访问者设计模式 这种模式的问题是
struct Visitor
{
virtual void visit(ParameterLimitedInt& wheel) = 0;
virtual void visit(ParameterAnyInt& engine) = 0;
virtual void visit(ParameterFilename& body) = 0;
};
是否有任何解决方案可以通过任何其他方式获得这种行为,而无需事先了解所有具体类型,也无需获得原始访客
编辑:,但问题仍然是一样的,该方法实际上依赖于动态强制转换,我试图将其作为一种(即使很弱)RTTI方法来避免 也许最好是考虑一些解决方案,甚至不引用访客模式,并清理我们的头脑。其目的只是具有以下功能:
Widget* CreateWidget(const Parameter& p)
如果我理解正确,每个“具体”参数的行为会有所不同,而不会丢失其类型的信息
我们有一个可以使用不同硬件选项的对象。为了实现这一点,我们使用了设备的抽象接口。这个设备有一系列的功能,可以在某些事件中触发。使用方法相同,但设备的各种实现要么具有完全充实的功能,要么立即返回。为了让生活更轻松,函数是无效的,当出现问题时会抛出异常。我使用了(“非循环访问者”)以获得良好的效果;在某种程度上,它可以在不改变现有类的情况下向层次结构中添加新类。为了完整起见: 当然,完全可以为对象编写自己的多方法指针表实现,并在运行时手动计算方法地址。在实现多方法(尽管是在编译器中)这一主题上,有一个由Stroustup提出的问题
我真的不会建议任何人这样做。让实现运行良好是相当复杂的,使用它的语法可能会非常笨拙且容易出错。如果其他一切都失败了,这可能仍然是一条路。我很难理解您的要求。但是,用我自己的话来说,我所理解的情况是这样的:
- 您有一个抽象的参数类,它最终被子类化为一些具体的类(例如:ParameterLimitedInt)
- 您有一个单独的GUI系统,它将以通用方式传递这些参数,但关键是它需要呈现特定于参数类的具体类型的GUI组件
- 限制是您不想执行RTTID,也不想编写代码来处理每种可能的具体参数类型
- 您可以使用访问者模式
class Visitor
{
public:
template< class T > void visit( const T& param ) const
{
assert( false && "this parameter type not specialised in the visitor" );
}
void visit( const ParameterLimitedInt& ) const; // specialised implementations...
}
类访问者
{
公众:
模板<类别T>无效访问(常量T和参数)常量
{
断言(false&“此参数类型不专门用于访问者”);
}
void visit(const参数limitedint&)const;//专门的实现。。。
}
因此,如果accept()返回false,您就知道该参数的具体类型尚未实现访问者模式(如果有其他逻辑,您更愿意根据具体情况处理)。如果访问者模式中的assert()被触发,那是因为它没有访问您已经实现了专门化的参数类型
所有这一切的一个缺点是,不受支持的访问只在运行时被捕获。对于一个通用的实现,我建议,这篇文章的一部分。这篇文章似乎消失了,真是太遗憾了:它激起了我的兴趣。我想八年在互联网上是永恒的。@Nicole
Widget* CreateWidget(const Parameter& p)
class Visitor
{
public:
template< class T > void visit( const T& param ) const
{
assert( false && "this parameter type not specialised in the visitor" );
}
void visit( const ParameterLimitedInt& ) const; // specialised implementations...
}