(不管你怎么称呼它的信号,槽,事件,改变广播/监听器,或)C ++ 11观察者模式 [英] C++11 observer pattern (signals, slots, events, change broadcaster/listener, or whatever you want to call it)
问题描述
使用取得了C ++ 11的变化(如列入的std ::绑定
),是否有实现一个简单的单线程观察者推荐的方法不依赖模式上的任何外部的核心语言和标准库(如的boost ::信号
)?
With the changes made in C++11 (such as the inclusion of std::bind
), is there a recommended way to implement a simple single-threaded observer pattern without dependence on anything external to the core language or standard library (like boost::signal
)?
修改
如果有人可以张贴一些code表示使用了新的语言功能如何在的boost ::信号
依存度可以降低,这将仍然是非常有用的。
If someone could post some code showing how dependence on boost::signal
could be reduced using new language features, that would still be very useful.
推荐答案
我觉得绑定
使得它的更容易的创建插槽(CFR。 'preferred'语法主场迎战便携的语法 - 这一切要离开)。观察者的管理,但是,不变得不太复杂。
I think that bind
makes it easier to create slots (cfr. the 'preferred' syntax vs. the 'portable' syntax - that's all going away). The observer management, however, is not becoming less complex.
但作为@R。 Martinho费尔南德斯提到:一个的std ::矢量<的std ::功能< R(A1)>方式>
现在是轻松无麻烦创建一个(人工)'纯虚'的接口类
But as @R. Martinho Fernandes mentions: an std::vector<std::function< r(a1) > >
is now easily created without the hassle for an (artificial) 'pure virtual' interface class.
根据要求:在连接管理的想法 - 也许完全错误的,但你会得到的想法:
Upon request: an idea on connection management - probably full of bugs, but you'll get the idea:
// note that the Func parameter is something
// like std::function< void(int,int) > or whatever, greatly simplified
// by the C++11 standard
template<typename Func>
struct signal {
typedef int Key; //
Key nextKey;
std::map<Key,Func> connections;
// note that connection management is the same in C++03 or C++11
// (until a better idea arises)
template<typename FuncLike>
Key connect( FuncLike f ) {
Key k=nextKey++;
connections[k]=f;
return k;
}
void disconnect(Key k){
connections.erase(k);
}
// note: variadic template syntax to be reviewed
// (not the main focus of this post)
template<typename Args...>
typename Func::return_value call(Args... args){
// supposing no subcription changes within call:
for(auto &connection: connections){
(*connection.second)(std::forward(...args));
}
}
};
用法:
signal<function<void(int,int)>> xychanged;
void dump(int x, int y) { cout << x << ", " << y << endl; }
struct XY { int x, y; } xy;
auto dumpkey=xychanged.connect(dump);
auto lambdakey=xychanged.connect([&xy](int x, int y){ xy.x=x; xy.y=y; });
xychanged.call(1,2);
这篇关于(不管你怎么称呼它的信号,槽,事件,改变广播/监听器,或)C ++ 11观察者模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!