C ++でコールバックを実装するにはどうすればよいですか?を読む必要があります。オブザーバーパターンへの参照に特に注意してください。このように緊密に結合されたクラスが2つある場合は、それらのテストがすぐに悪夢になるため、設計を再考する必要があります。
そうは言っても、これがあなたが始めた実装を終了する方法です...
#include <iostream>
class First;
// Typedefs make this much more readable: http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.5
typedef void (First::*SecondTriggeredCallback)(void);
// And macros make the call much more readable: http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.6
#define CALL_MEMBER_FN(object, ptrToMember) ((object).*(ptrToMember))
class Second
{
public:
// You'll also need an *instance* of the First class
Second(SecondTriggeredCallback SecondTriggered, First& first)
{
CALL_MEMBER_FN(first, SecondTriggered)();
}
};
class First
{
private:
Second *second;
public:
First()
{
std::cout << "first class was created" << std::endl;
second = new Second(&First::SecondTriggered, *this);
}
~First()
{
delete second;
}
void SecondTriggered()
{
std::cout << "second class was created and responded" << std::endl;
}
};
int main()
{
First first;
}
それが実行されるのを見てください!
テンプレートを使用してカップリングを削除するバージョンは次のとおりです。
#include <iostream>
// Macros make the call much more readable: http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.6
#define CALL_MEMBER_FN(object, ptrToMember) ((object).*(ptrToMember))
template <class T>
struct Second
{
// Typedefs make this much more readable: http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.5
typedef void (T::*SecondTriggeredCallback)(void);
// You'll also need an *instance* of the "T" class
Second(SecondTriggeredCallback SecondTriggered, T& t)
{
CALL_MEMBER_FN(t, SecondTriggered)();
}
};
class First
{
public:
First()
:second(NULL)
{
std::cout << "first class was created" << std::endl;
second = new Second<First>(&First::SecondTriggered, *this);
}
~First()
{
delete second;
}
void SecondTriggered()
{
std::cout << "second class was created and responded" << std::endl;
}
private:
First(const First&);
First& operator =(const First&);
Second<First>* second;
};
int main()
{
First first;
}