プロジェクト内でSubject-Observerパターンを成功させて使用しています。 Subject-Observerとメッセージタイプの数が5以上に増えたので、私はそれぞれ同じコードパターンを複製しています。 Subject-Observerパターンのクラステンプレートに切り替えようとしています。しかし、私は、私は(努力にもかかわらず)を解決することができなかったコンパイルエラーに貼り付けています:C++エラー:(基底クラステンプレートから)サブクラスへの無効な変換
Building file: ../main.cpp
Invoking: GCC C++ Compiler
g++ -std=c++0x -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.cpp"
../main.cpp: In instantiation of ‘Observer<T_subject, T_message>::~Observer() [with T_subject = RotationSubject; T_message = long unsigned int]’:
../main.cpp:49:7: required from here
../main.cpp:39:15: error: invalid conversion from ‘Observer<RotationSubject, long unsigned int>* const’ to ‘RotationObserver*’ [-fpermissive]
~Observer(){ subject->UnregisterObserver(this); }
^
../main.cpp:10:7: error: initializing argument 1 of ‘void Subject<T_observer, T_message>::UnregisterObserver(T_observer*) [with T_observer = RotationObserver; T_message = long unsigned int]’ [-fpermissive]
void UnregisterObserver( T_observer* observer){
^
make: *** [main.o] Error 1
最小限の作業のコード例です:
#include <vector>
template <class T_observer, typename T_message> class Subject
{
public:
void RegisterObserver(T_observer* observer){
observers.push_back(observer);
}
void UnregisterObserver( T_observer* observer){
for (auto itr = begin(observers); itr != end(observers); itr++){
if (*itr == observer){
itr = observers.erase(itr);
if (itr == observers.end()) break;
}
}
}
void NotifyObservers(T_message message){
for(auto const& itr : observers){
itr->ReceiveMessage(message);
}
}
std::vector < T_observer * > observers;
};
template <class T_subject, typename T_message> class Observer
{
public:
Observer(T_subject* subject)
: subject(subject)
{
subject->RegisterObserver(this);
}
~Observer(){ subject->UnregisterObserver(this); }
virtual void ReceiveMessage(T_message message) {};
// Observer sub-classes define ReceiveMessage
T_subject* subject;
};
class RotationSubject;// forward declaration prevents circular dependency
class RotationObserver : public Observer< RotationSubject, unsigned long>
{
public:
RotationObserver(RotationSubject* rotation_subject);
};
class RotationSubject : public Subject< RotationObserver, unsigned long>
{ };
int main(int argc, char * argv[]){
RotationSubject* pRotSubject = new RotationSubject();
RotationObserver* pRotObserver = new RotationObserver(pRotSubject);
pRotObserver->~RotationObserver();
return 0;
}
意図は、これらのベースから派生するサブクラスを定義することですここにはRotationSubject
とRotationObserver
と表示されています。タイプ識別子T_observer
およびT_subject
の動機付けは、どのサブクラスが対になるかを特定することである。 RotationObservers
は、RotationSubjects
を観察し、ローテーションメッセージタイプ(T_message
はこの例ではunsigned long
)を受信する必要があります。
私が正しくエラーメッセージを読めば、Observer<RotationSubject, long unsigned int>* const
はないRotationObserver*
、またはコンパイラが変換する方法を認識していないです。
循環依存性とconstを原因として探求しましたが、成功しませんでした。
このエラーメッセージの原因を理解し、可能であれば修正するための最小限の編集を手伝ってください。これが私の主な質問です。
私は全く異なるデザインと改善のための提案をしています。
ありがとうございます。答え:両方の問題を正しく特定しました。継承と型キャスト'static_cast'は簡単に追加できましたが、継承パターンを修正するにはもう少し読んでいました。 –
@TysonHilmer:うれしいよ! –