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

C++ 在不知道完整层次结构的情况下进行双重分派,c++,double-dispatch,C++,Double Dispatch,我想用C++实现以下内容: 我希望有一个类的一堆子类,能够调用一个函数,该函数接受一对这些类型的对象。应该有一个通用实现,用于混合类型或基本类型和专用实现,如果将相同派生类型的两个对象用作参数,则会调用该实现 据我所知,这是双重分派的一个经典应用程序。但是,我有以下限制: 必须能够从现有类派生新类,并在不更改现有类的情况下为这些新类添加新的对函数,例如在外部库中 我在中提出的方法是错误的,在那里提出的解决方案只适用于在编写基类时已知的类型 有没有关于如何实施的建议?这可能吗 更新:代码可以说上千

我想用C++实现以下内容:

我希望有一个类的一堆子类,能够调用一个函数,该函数接受一对这些类型的对象。应该有一个通用实现,用于混合类型或基本类型和专用实现,如果将相同派生类型的两个对象用作参数,则会调用该实现

据我所知,这是双重分派的一个经典应用程序。但是,我有以下限制:

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

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

有没有关于如何实施的建议?这可能吗

更新:代码可以说上千字。以下方法有效:

#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*其他)
{
其他->预合成(本);
}
虚拟空间预合成(A*其他)
{
std::cout预合成(this);
}
虚拟空间预合成(B*其他)
{
std::cout“与B对象预合成”
}

但是,在实现
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 );
    }
}
virtualvoidfoo(base*argument\u base){
if(派生*参数=动态\u转换<派生*>(参数\u基)){
argument->something=pair\u match\u foo;
}否则{
基类::foo(参数基类);
}
}

这对对象中是否包含此对象?好吧,如果您愿意,可以。我将在问题中添加一个简短的示例。wikipedia示例的问题是,在实现基类时,您必须了解所有派生类,而我无法做到这一点。我正在寻找一种方法,允许我以后添加派生类,而无需添加派生类更改基类。为了更精确,如果我只有一个类层次结构,而不是两个,我需要双重分派。没有“目标类”,因为类本身就是它的目标。这没有问题,但在编写bas类时需要知道整个类层次结构,这不是我想要的。@lytenyn:对不起,我是一个有点生疏。我也不清楚
compose
是用于操作还是调度机制本身……无论如何,请参阅更新。@Potatoswatter:谢谢,这会很好地解决问题。但是,我不愿意使用
dynamic\u cast
,但我无法指出原因。它确实很慢,但这不是无论如何,这是一个时间关键的操作。你能想出一些不涉及
dynamic\u cast
的东西吗?或者告诉我,我的不安感觉是没有道理的?@lytenyn:我认为这是一个不算数的用法:v)。如果你愿意,你可以用一个额外的虚拟函数来代替它,以返回一个标识子层次结构的
enum
值hy,或者只是一个具有相同信息的成员变量。我认为这种选择不太优雅。许多学生已经被教导使用
dynamic\u cast
,其中
static\u cast
是合适的。这是一个巨大的危险信号,我可以想象对操作符本身的强烈反对。