我越来越多地进入Pimpl idiom(指向实际类实现的私有不透明指针)。但我仍然有一个困扰我的问题。
这个成语\设计模式如何处理公共类中的信号(如boost或qt信号)?
class my_class : public QObject
{
Q_OBJECT
public:
void monitorstuff();
signal:
void needupdate();
private:
class impl; unique_ptr<impl> pimpl; // opaque type here
};
class my_class::impl {
void reallymonitorstuff();
};
my_class::impl::reallymonitorstuff()
{
...
//update required here
...
}
void my_class::monitorstuff()
{
pimpl->reallymonitorstuff();
}
pimpl
中的所有信号,连接外部类的信号?有点烦人的信号是公共可用信号的两倍,当我需要交换实例时也很烦人。答案 0 :(得分:1)
我是否复制了pimpl中的所有信号,并连接外部类的信号?有点烦人的信号是公共可用信号的两倍,当我需要交换实例时也很烦人。
不,你不需要这样做。
我是否将公共实例作为参数传递给直接调用公共信号的私有实例
这也没必要。
我没有听说过另一种设计机制?
这也没必要。
假设my_class::monitorstuff
应该发出信号,我认为您需要的只是:
void my_class::monitorstuff()
{
pimpl->reallymonitorstuff();
emit <<Details of signal>>;
}
pimpl
无需关注信号或插槽。
答案 1 :(得分:0)
总的来说,我真的没有看到这个问题。公共类应该转发所有对impl的调用,包括连接插槽的调用。 impl包含信号,而不是公共类。例如,使用Boost.Signals2:
#include <memory>
#include <boost/signals2.hpp>
#include <iostream>
using signal_type = boost::signals2::signal<void()>;
using slot_type = signal_type::slot_type;
class my_class {
public:
my_class();
void monitorstuff();
void connect(const slot_type& slot);
private:
struct impl; std::unique_ptr<impl> pimpl;
};
struct my_class::impl {
signal_type signal;
void reallymonitorstuff();
void connect(const slot_type& slot){ signal.connect(slot); }
};
void
my_class::impl::reallymonitorstuff() {
//...
signal();
//...
}
void my_class::monitorstuff() {
pimpl->reallymonitorstuff();
}
void my_class::connect(const slot_type& slot) {
pimpl->connect(slot);
}
my_class::my_class() : pimpl(std::make_unique<my_class::impl>()){}
int main() {
my_class mc;
auto slot = []{ std::cout << "Notified!\n"; };
mc.connect(slot);
mc.monitorstuff();
}
我想知道你的问题是否更具体针对Qt。