在不知道完整层次结构的情况下进行双重分派

Double dispatch without knowing the full hierarchy

本文关键字:分派 情况下 不知道 层次结构      更新时间:2023-10-16

我想在c++中实现以下事情:

我想有一个单一类的一堆子类,能够调用函数,该函数接受任何这些类型的对对象。应该有一个泛型实现,用于混合类型或基类型调用;专用实现,如果使用相同派生类型的两个对象作为参数,则调用该实现。

据我所知,这是一个经典的双调度应用。但是,我有以下约束:

必须能够从现有类派生出新类,并在不改变现有类的情况下为这些新类添加新的pair函数,例如在外部库中。

我在上一个问题中提出的方法是错误的,那里提出的解决方案只适用于在编写基类时已知的类型。

对如何实现这一点有什么建议吗?这可能吗?

Update:代码千言万语。下面的方法可以工作:

#include <iostream>
class B;
class A
{
public:
  virtual void PostCompose(A* other)
    {
      other->PreCompose(this);
    }
  virtual void PreCompose(A* other)
    {
      std::cout << "Precomposing with an A object" << std::endl;
    }
  virtual void PreCompose(B* other);
};
class B : public A
{
public:
  using A::PreCompose;
  virtual void PostCompose(A* other)
    {
      other->PreCompose(this);
    }
  virtual void PostCompose(B* other)
    {
      other->PreCompose(this);
    }
  virtual void PreCompose(B* other)
    {
      std::cout << "Precomposing with a B object" << std::endl;
    }
};
void A::PreCompose(B* other)
  {
    PreCompose((A*)other);
  }
int main()
{
  B b;
  A* p = &b;
  p->PostCompose(p); // -> "Precomposing with a B object"
}

,但在实现A时需要了解B。有没有更好的办法?

由于派生类只需要检测参数类型是否与对象类型匹配,因此您可以使用直接的检查。

virtual void foo( base *argument_base ) {
    if ( derived *argument = dynamic_cast< derived * >( argument_base ) ) {
        argument->something = pair_match_foo;
    } else {
        base_class::foo( argument_base );
    }
}