以前用过VB、Delphi,C++Builder的老程序员都知道,事件驱动在可视化程序设计中有非常重要的位置,用起来非常方便,现在的Qt框架也是,不管是信号还是事件,或者Java中的接口,目的是让未来开发人员一起设计,一起扩展。事件的主要目的是告诉别人发生了什么事,接口(虚函数virtual)是要别人重新设计一下某方面的功能,下面看一下C++事件设计的例子:
class my_window
{
private:
_Color _c;
public:
void setColor(const _Color& c) {
_c = c;
}
};
在my_window颜色发生改变时,要发出一个事件,表明color发生了改变,这里有三种方式
告诉程序设计的使用者。
第一种,利用std::function:
class my_window
{
private:
_Color _c;
public:
//第一种
std::function<void(const _Color& c)> pf_colorChanged = 0;
public:
void setColor(const _Color& c) {
if (_c != c) {
if (pf_colorChanged != 0)
pf_colorChanged(c);
}
_c = c;
}
};
int main(int argc, char* argv[])
{
QApplication a(argc, argv); //注意,这里是QApplication
my_window w;
w.pf_colorChanged = [](const _Color& c) {
std::cout << "Window颜色发生了改变\n";
};
w.setColor(_Color::Blue);
return a.exec();
}
输出:
第二种,利用函数指针
class my_window
{
private:
_Color _c;
public:
void (*pf_colorChanged)(const _Color& c) = 0;
public:
void setColor(const _Color& c) {
if (_c != c) {
if (pf_colorChanged != 0)
pf_colorChanged(c);
}
_c = c;
}
};
int main(int argc, char* argv[])
{
QApplication a(argc, argv); //注意,这里是QApplication
my_window w;
w.pf_colorChanged = [](const _Color& c) {
std::cout << "Window颜色发生了改变\n";
};
w.setColor(_Color::Blue);
return a.exec();
}
输出:
注意:上次说过第二种 Lambda 无法传递参数,使用起来不方便。
参见:再再接上一主题,在C++,函数指针问题,如何使用std::function 和 std::bind?-CSDN博客
第三种,利用函数模板:
class my_window
{
private:
_Color _c;
public:
public:
template<class fun>
void setColor(const _Color& c, fun f) {
if (_c != c) {
f(c);
}
_c = c;
}
void setColor(const _Color& c) {
_c = c;
}
};
int main(int argc, char* argv[])
{
QApplication a(argc, argv); //注意,这里是QApplication
my_window w;
w.setColor(_Color::Blue, [w](const _Color& c) {
std::cout << "Window颜色发生了改变\n";
});
return a.exec();
}
你认为那种好?
题外话:
为什么用pf_开头,看下图就知道了,如果一个不太熟悉Qt框架的人,要找信号和事件,每次都要去看源代码,几百个函数,烦死了。