用C++实现两个类层次结构的双重调度
Implementing double dispatch with two class hierarchies in C++
我想创建一个具有(浅层)EventObserver层次结构的事件调度系统。我认为双重调度将允许各种各样的Events和EventObserver,而不必为每个组合都有一个函数。
我有这样的代码:
class BaseObserver;
class BaseEvent {
public:
virtual std::string getName() { return "BaseEvent"; }
void beObservedBy( BaseObserver* obv );
};
class BaseObserver {
public:
virtual void observe( BaseEvent* evt ) {
std::cout << "BaseObserver observing: " << evt->getName() << "." << std::endl;
}
};
void BaseEvent::beObservedBy( BaseObserver* obv ) { obv->observe( this ); }
然后定义几个测试类:
class EventA : public BaseEvent {
public:
void beObservedBy( BaseObserver* obv ) { obv->observe( this ); }
virtual std::string getName() { return "I am an EventA"; }
};
class EventB : public BaseEvent {
public:
void beObservedBy( BaseObserver* obv ) { obv->observe( this ); }
virtual std::string getName() { return "I am an EventB"; }
};
class ObserverX : public BaseObserver {
virtual void observe( EventA* evt ) { std::cout << "ObserverX spotted an EventA" << std::endl; }
};
(这一切都遵循了C++中的双调度/多方法和维基百科上关于双调度的文章)
现在,当我调试双重调度时,会调用派生的Event类(比如EventA
)的beObservedBy
方法,并使用派生的EventObserver类,但会调用observe( BaseEvent* )
函数,而不是observe( EventA* )
我做错了吗?我试着用引用而不是指针,但没有得到爱。
问题在于您在ObserverX中定义了observe(EventA *evt)
。这会导致函数过载。但当您调用observe
时,参数是BaseEvent *
,而不是EventA *
。因此,改为调用基类方法。
派生类中的签名必须与基类中的签名匹配,否则它不会覆盖它,只是重载它(因此最终会得到两个函数——一个使用EventA *
,另一个使用BaseEvent *
)。
请尝试在ObserverX中定义observe(BaseEvent *evt)
。
您的基本观察者类需要知道如何观察任何事件类型,或者您的基本事件类需要知道任何观察者类型如何观察。否则,您的双重调度只会丢失从初始调度中获得的类型信息。
在您的情况下,如果您将virtual void observe( EventA* evt )
添加到BaseObserver
类中,那么EventA::beObservedBy
将调用该版本的observe方法,而ObserverX
将正确地覆盖它。
首先,Observer X中observe的签名与基类中的签名不同,并且它没有覆盖基类中的虚拟void observe(BaseEvent*evt)方法。相反,您定义了一个以EventA*为参数的新函数。
请记住,在C++中,函数签名由函数名称和参数列表组成,在本例中为
virtual void observe( BaseEvent* evt )
与不同
virtual void observe( EventA* evt )
- 如何重构类层次结构以避免菱形问题
- C++ 中模板化类型的类层次结构
- 为什么不同类型层次结构的指针之间的dynamic_cast定义得很好?
- 继承层次结构并将元素添加到向量
- C++ 类层次结构中的"对齐"是什么意思?
- 相同的层次结构,访问基类的受保护成员时的行为不同
- 类层次结构中的运算符重载
- 如何在层次结构中实现运算符使用?
- 反向层次结构中的可变参数模板参数
- 如何在继承层次结构中调用具有默认参数的构造函数?
- C++ 提升 - 包含类层次结构对象的类的序列化
- 在C++继承层次结构时提取实现者
- 在C++中将类实例添加到对象层次结构中的问题
- 确定大层次结构中基本指针的实际类型,无需dynamic_cast
- 在继承层次结构中复制和移动
- 模板冲突的类型-但类型应该是相同的cfr类层次结构
- 删除父/子窗口层次结构的最佳方法
- 是否可以使一个类成为两个不同层次结构的子类?
- 静态调度以使用聚合类型的层次结构更正成员方法
- 用C++实现两个类层次结构的双重调度