这段代码将问题提炼为本质:
基础设施类:
struct EventReceiverBase {
virtual ~EventReceiverBase() { }
};
template<typename T>
struct EventReceiver : public virtual EventReceiverBase {
virtual void receiveEvent(T* pSender) = 0;
};
struct EventSender {
EventReceiverBase* pReceiver;
template<typename T>
void sendEvent(T* pSender) {
EventReceiver<T>* pCastedReceiver =
dynamic_cast<EventReceiver<T>*>(pReceiver);
// HERE IS THE PROBLEM
// pCastedReceiver is null. T is BaseSender. The pointer
// being casted is really of type EventReceiver<DerivedSender>*,
// but it tries to cast to EventReceiver<BaseSender>*, and that
// fails.
pCastedReceiver->receiveEvent(pSender);
}
};
用户类别:
struct BaseSender : public virtual EventSender {
void f() {
sendEvent(this);
}
};
struct DerivedSender : public BaseSender { };
struct MyClass : public virtual EventReceiver<DerivedSender> {
void receiveEvent(DerivedSender* pSender) { }
};
int main() {
MyClass my;
DerivedSender derivedSender;
derivedSender.pReceiver = &my;
derivedSender.f();
}
我可以改写这个问题(没有双关语)以避免这个问题吗?我希望使用户类尽可能简单,同时尽可能接近这种方式公开事件发送和接收功能。
例如,我可以通过让 MyClass 也从 EventReceiver<BaseSender> 派生来“修复”它,但我真的很想避免这种情况,因为这意味着每个接收事件的类都需要额外的工作。
编辑:可执行粘贴: http: //liveworkspace.org/code/4bm6OU $13