Как видно из приведенного ниже кода (реализованного как иллюстрация проблемы), я пытаюсь отправить сигнал из внутреннего класса в средний класс, который передаст его внешнему классу.
#include <boost/bind.hpp>
#include <boost/signals2.hpp>
#include <iostream>
class inner {
public:
template <class T>
void register_callback(boost::function<void(T *)> cb, T *obj)
{
sig_inner_.connect(boost::bind(cb, boost::ref(obj)));
}
void trigger()
{
std::cout << "inner" << std::endl;
sig_inner_();
}
private:
boost::signals2::signal<void()> sig_inner_;
};
class mid {
public:
mid() { inner_obj.register_callback<mid>(&mid::handle_sig_mid, this); }
template <class T>
void register_callback(boost::function<void(T *)> cb, T *obj)
{
sig_mid_.connect(boost::bind(cb, boost::ref(obj)));
}
void trigger() { sig_mid_(); }
void inner_trigger() { inner_obj.trigger(); }
void handle_sig_mid()
{
std::cout << "mid" << std::endl;
trigger();
}
private:
boost::signals2::signal<void()> sig_mid_;
inner inner_obj;
};
class outer {
public:
outer() { mid_obj.register_callback<outer>(&outer::handle_sig_outer, this); }
void inner_trigger() { mid_obj.inner_trigger(); }
private:
mid mid_obj;
void handle_sig_outer() { std::cout << "outer" << std::endl; }
};
int main()
{
outer outer_obj;
outer_obj.inner_trigger();
return 0;
}
Вместо желаемого результата:
inner
mid
outer
При запуске программы на самом деле происходит следующее:
inner
mid
mid
Вслед за аварией.
Я уже заметил, что адрес this в обработчике отличается от того, что я ожидал бы в обычном методе, но я не знаю, как это обойти.
Единственное решение, которое я нашел для этого, заключалось в подключении сигнала во внешнем классе к его обработчику, а затем сохранении указателя (в данном случае unique_ptr) во внутреннем классе, что позволило избежать необходимости его передачи, но это не чувствуется. как безопасный способ использования сигналов.
Я новичок в С++ и, в частности, в повышении, поэтому я действительно не знаю, как вызывать обратные вызовы во внешнем классе из внутреннего класса чистым и безопасным способом.