C双重调度“可扩展”没有RTTI

前端之家收集整理的这篇文章主要介绍了C双重调度“可扩展”没有RTTI前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
有没有人知道如何在C中正确处理双重调度而不使用RTTI和dynamic_cast<>还有一个解决方案,其中类层次结构是可扩展的,即基类可以从进一步派生,它的定义/实现不需要知道它?
我怀疑没有办法,但我很高兴被证明是错的:)

解决方法

要实现的第一件事是双重(或更高阶)调度不能扩展.单身
dispatch和n类型,你需要n个函数;用于双重发送n ^ 2,依此类推.你怎么
处理此问题部分决定了您如何处理双重调度.一个明显的解决方案是
通过创建一个封闭的层次结构来限制派生类型的数量;在这种情况下,双重发送可以
使用访客模式的变体轻松实现.如果不关闭层次结构,
那么你有几种可能的方法.

如果你坚持认为每一对都对应一个函数,那么你基本上需要一个:

std::map<std::pair<std::type_index,std::type_index>,void (*)(Base const& lhs,Base const& rhs)>
                dispatchMap;

(根据需要调整函数签名.)您还必须实现n ^ 2函数,和
将它们插入dispatchMap. (我假设你使用免费功能;没有
将它们放入其中一个类而不是另一个类的逻辑原因.)之后,您调用

(*dispatchMap[std::make_pair( std::type_index( typeid( obj1 ) ),std::type_index( typeid( obj2 ) )])( obj1,obj2 );

(你显然想把它包装成一个函数;它不是你想分散的东西
遍布代码.)

一个小变体就是说只有某些组合是合法的.在这种情况下,您可以使用
在dispatchMap上找到,如果找不到要查找的内容,则会生成错误.
(期待很多错误.)如果您可以定义某种默认值,则可以使用相同的解决方
行为.

如果你想100%正确地完成它,一些函数能够处理中间类
和它的所有衍生物,你需要某种更动态的搜索,并订购
控制重载分辨率.考虑例如:

Base
         /       \
        /         \
       I1          I2
      /  \        /  \
     /    \      /    \
    D1a   D1b   D2a   D2b

如果你有f(I1,D2a)和f(D1a,I2),应选择哪一个.最简单的解决方
只是一个线性搜索,选择可以调用的第一个(由dynamic_cast确定)
指向对象的指针),并手动管理插入顺序以定义重载
你希望的决议.但是,使用n ^ 2个函数,这可能会很快变慢.以来
有一个排序,应该可以使用std :: map,但是排序函数会去
实际上是非常重要的(并且仍然必须在整个过程中使用dynamic_cast)
地点).

考虑到所有事情,我的建议是将双重调度限制在小的,封闭的层次结构中,并坚持访客模式的一些变体.

猜你在找的C&C++相关文章