使用信號(hào)槽
信號(hào)槽是偉大的工具,但是如何能更好的使用它們?相比于直接函數(shù)調(diào)用,有三點(diǎn)值得我們的注意。一個(gè)信號(hào)槽的調(diào)用:
或許會(huì)比直接函數(shù)調(diào)用耗費(fèi)更多的時(shí)間/空間;
可能不能使用 inline;
對(duì)于代碼閱讀者來說可能并不友好。
使用信號(hào)槽進(jìn)行解耦,我們獲得的最大的好處是,連接兩端的對(duì)象不需要知道對(duì)方的任何信息。Button 同動(dòng)作的連接是一個(gè)很典型的案例。例如如下信息:
class Elevator
{
public:
enum Direction { DownDirection=-1, NoDirection=0, UpDirection=1 };
enum State { IdleState, LoadingState, MovingState };
// ...
// signals:
void floorChanged( int newFloor );
void stateChanged( State newState );
void directionChanged( Direction newDirection );
};Elevator 類,也就是電梯,不需要知道有多少顯示器正在監(jiān)聽它的信號(hào),也不需要知道這些顯示器的任何信息。每一層可能有一個(gè)屏幕和一組燈,用于顯示電梯的當(dāng)前位置和方向,另外一些遠(yuǎn)程操控的面板也會(huì)顯示出同樣的信息。電梯并不關(guān)心這些東西。當(dāng)它穿過(或者停在)某一層的時(shí)候,它會(huì)發(fā)出一個(gè) floorChanged(int) 信號(hào)。或許,交通信號(hào)燈是更合適的一個(gè)例子。
你也可以實(shí)現(xiàn)一個(gè)應(yīng)用程序,其中每一個(gè)函數(shù)調(diào)用都是通過信號(hào)來觸發(fā)的。這在技術(shù)上說是完全沒有問題的,然而卻是不大可行的,因?yàn)樾盘?hào)槽的使用無疑會(huì)喪失一部分代碼可讀性和系統(tǒng)性能。如何在這其中做出平衡,也是你需要考慮的很重要的一點(diǎn)。
Qt 方式
了解 Qt 信號(hào)槽最好的莫過于 Qt 的文檔。不過,這里我們從一個(gè)小例子來了解信號(hào)槽的 Qt 方式的使用。
// Qt Signals and Slots
class Button : public QObject
{
Q_OBJECT
Q_SIGNALS:
void clicked();
};
class Page : public QObject
{
Q_OBJECT
public Q_SLOTS:
void reload();
};
// given pointers to an actual Button and Page:
connect(button, SIGNAL(clicked()), page, SLOT(reload()));Boost.Signals 方式
了解 Boost.Signals 的最好方式同樣是 Boost 的文檔。這里,我們還是先從代碼的角度了解一下它的使用。
// Boost.Signals
class Button
{
public:
boost::signal< void() > clicked;
};
class Page
{
public:
void reload();
};
// given pointers to an actual Button and Page:
button->clicked.connect( boost::bind(&Page::reload, page) );對(duì)比
或許你已經(jīng)注意到上面的例子中,無論是 Qt 的實(shí)現(xiàn)方式還是 Boost 的實(shí)現(xiàn)方式,除了必須的 Button 和 Page 兩個(gè)類之外,都不需要額外的類。兩種實(shí)現(xiàn)都解決了類爆炸的問題。下面讓我們對(duì)照著來看一下我們前面的分析。現(xiàn)在我們有:
本文導(dǎo)航
- 第1頁: 首頁
- 第2頁: 使用信號(hào)槽
- 第3頁: 兩個(gè)不同的術(shù)語以及各自的動(dòng)作:信號(hào)和槽