QT中的訊號-槽比我們常用的callback到底牛在哪裡?
剛剛接觸qt, 發現有一個東西叫signal slot ,翻譯為訊號槽。
免責宣告,我是一個beginner。Google了很多資料,很多文章寫signal slot的。所以,這裡只是把我個人覺得精彩的地方整理在一起,再偶爾加上一點點自己的看法而已。
看問題,再stackoverflow上看到這樣一個提問,大意思是這樣:
他們團隊的qt專案中,一位資深的軟體工程師運用了大量的c-style的回撥函式,而沒用使用qt中很精妙的signal slot機制。
回撥有哪些缺點?
Callbacks have two fundamental flaws: Firstly, they are not type-safe. We can never be certain that the processing function will call the callback with the correct arguments. Secondly, the callback is strongly coupled to the processing function since the processing function must know which callback to call.
什麼叫型別安全?
型別安全很大程度上可以等價於記憶體安全,型別安全的程式碼不會試圖訪問自己沒被授權的記憶體區域。“型別安全”常被用來形容程式語言,其根據在於該門程式語言是否提供保障型別安全的機制;有的時候也用“型別安全”形容某個程式,判別的標準在於該程式是否隱含型別錯誤。型別安全的程式語言與型別安全的程式之間,沒有必然聯絡。好的程式設計師可以使用型別不那麼安全的語言寫出型別相當安全的程式,相反的,差一點兒的程式設計師可能使用型別相當安全的語言寫出型別不太安全的程式。絕對型別安全的程式語言暫時還沒有。
什麼是訊號、槽?
A signal is an observable event, or at least notification that the
event happened.
A slot is a potential observer, typically in the form a function to be
called.
You connect a signal to a slot to establish the observableobserver
relationship.
訊號槽有啥缺點呢?
Compared to callbacks, signals and slots are slightly slower because of the increased flexibility they provide, although the difference for real applications is insignificant.
In general, emitting a signal that is connected to some slots, is approximately ten times slower than calling the receivers directly, with non-virtual function calls.
This is the overhead required to locate the connection object, to safely iterate over all connections (i.e. checking that subsequent receivers have not been destroyed during the emission), and to marshall any parameters in a generic fashion. While ten non-virtual function calls may sound like a lot, it’s much less overhead than any new or delete operation, for example. As soon as you perform a string, vector or list operation that behind the scene requires new or delete, the signals and slots overhead is only responsible for a very small proportion of the complete function call costs. The same is true whenever you do a system call in a slot; or indirectly call more than ten functions. The simplicity and flexibility of the signals and slots mechanism is well worth the overhead, which your users won’t even notice.
官方出品(節選):
In Qt, we have an alternative to the callback technique: We use signals and slots. A signal is emitted when a particular event occurs. Qt’s widgets have many predefined signals, but we can always subclass widgets to add our own signals to them. A slot is a function that is called in response to a particular signal. Qt’s widgets have many pre-defined slots, but it is common practice to subclass widgets and add your own slots so that you can handle the signals that you are interested in.
簡單的例子:
/ Header file
#include <QObject>
class Counter : public QObject
{
Q_OBJECT
public:
Counter() { m_value = 0; }
int value() const { return m_value; }
public slots:
void setValue(int value);
signals:
void valueChanged(int newValue);
private:
int m_value;
};
// .cpp file
void Counter::setValue(int value)
{
if (value != m_value) {
m_value = value;
emit valueChanged(value);
}
}
// Later on...
Counter a, b;
QObject::connect(&a, SIGNAL(valueChanged(int)),
&b, SLOT(setValue(int)));
a.setValue(12); // a.value() == 12, b.value() == 12
b.setValue(48); // a.value() == 12, b.value() == 48
Here is that code rewritten using callbacks:
#include <functional>
#include <vector>
class Counter
{
public:
Counter() { m_value = 0; }
int value() const { return m_value; }
std::vector<std::function<void(int)>> valueChanged;
void setValue(int value);
private:
int m_value;
};
void Counter::setValue(int value)
{
if (value != m_value) {
m_value = value;
for (auto func : valueChanged) {
func(value);
}
}
}
// Later on...
Counter a, b;
auto lambda = [&](int value) { b.setValue(value); };
a.valueChanged.push_back(lambda);
a.setValue(12);
b.setValue(48);
相關文章
- Qt 中多執行緒對應的訊號槽QT執行緒
- Qt之訊號與槽QT
- Qt5的訊號和槽函式QT函式
- 02_QT訊號和槽QT
- Qt - 訊號與槽的第五個引數QT
- Qt 訊號槽傳遞指標QT指標
- Qt自定義訊號槽的使用淺析+例項QT
- 《Qt5:訊號和槽使用示例》QT
- QT 控制檯訊號與槽簡例QT
- Qt 5中使用lambda表示式連線訊號和槽QT
- C++ Qt開發:如何使用訊號與槽C++QT
- QT槽函式獲取訊號傳送物件QT函式物件
- Qt 自動連線機制訊號與槽QT
- Array.prototype.forEach(callback) 的 callback 到底執行了幾次?
- Qt學習第三篇(訊號槽函式的連線)QT函式
- Qt訊號與槽使用方法最完整總結QT
- Redis到底快在哪裡Redis
- 談 C++17 裡的 Observer 模式 - 4 - 訊號槽模式C++Server模式
- Spring Boot 中的靜態資源到底要放在哪裡?Spring Boot
- 海外公司比我們強在哪裡?歐洲遊戲公司9天行程拜訪總結遊戲行程
- pyqt5中訊號與槽的認識QT
- C++《QT之按鍵QPushButton設定訊號與槽》C++QT
- QT從入門到入土(三)——訊號和槽機制QT
- QT學習筆記1(安裝、建立和訊號與槽)QT筆記
- 中國做3A遊戲到底難在哪裡?遊戲
- 基於雲的CRM系統到底好在哪裡?
- Java反射慢,到底慢在哪裡?Java反射
- 你和牛人到底差在哪裡?
- MVVM 到底比 MVC 好在哪裡?MVVMMVC
- python爬蟲遠比我們想的複雜Python爬蟲
- PyQT5訊號與槽的連線QT
- 火遍全世界的Python好在哪裡?為啥這麼牛?Python
- 阿里開源的32B大模型到底強在哪裡?阿里大模型
- ChatGPT 到底強大在哪裡?(文末有彩蛋)ChatGPT
- 他們手裡的“CISP”,價值到底有多高
- 輕量級工具Vite到底牛在哪, 一文全知道Vite
- 月入5000和20000的程式設計師,差距到底差在哪裡?程式設計師
- C++11 實現簡易的訊號槽。C++
- 高階程式設計師到底強在哪裡?程式設計師