このコードは、問題を本質的に抽出します。
インフラストラクチャ クラス:
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