我需要將QWebSocket的binaryMessageReceived信號連接到我的槽,該槽會修改QByteData
。QByteData可能很大,所以每次將其再次復制到可改變的變數中可能非常昂貴。我想重新使用現有的QByteData
當我嘗試用下面的槽編譯時void route(QByteArray& msg)。
我得到了編譯錯誤
/usr/include/qt/QtCore/qobject.h:255:9: error: static斷言失敗。信號和槽引數不兼容。
255 | Q_STATIC_ASSERT_X((QtPrivate:: CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments> ::value),
| ^~~~~~~~~~~~~~~~~
/usr/include/qt/QtCore/qobject. h:255:9: note: '(((int)QtPrivate:: CheckCompatibleArguments<QtPrivate::List<constQByteArray&>, QtPrivate::List<QByteArray&>:value) ! = 0)' 評估為false。
但是如果我把槽改成
void route(const QByteArray& msg)。
它編譯得很好
我是這樣連接槽的:-connect(this, &QWebSocket::binaryMessageReceived, this, & WSManager::route) 。
uj5u.com熱心網友回復:
你可能不想這樣做。
如果以const &的形式傳遞,信號引數是不能被修改的。你甚至不確定發射器物件(QWebSocket)中的二進制資料的壽命。
QByteData從這里被發射出來。https://code.woboq.org/qt5/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp.html#181
嵌套在多個隱藏于API的類中,依靠這種屬性/資料是非常危險的。
QByteArray使用implicit-sharingQt機制,避免深度拷貝。
https://doc.qt.io/qt-5/implicit-sharing.html
這意味著你可以把物件傳來傳去,而不必擔心性能問題。如果在某些時候你需要修改它,由于移動運算子的存在,你最終可能會在資料的唯一實際實體上作業。
uj5u.com熱心網友回復:
我認為你可以連接到lambda,并在lambda函式中使用const_cast:
connect(this, &QWebSocket:: binaryMessageReceived, this, [this](const QByteArray & message) {
this->route(const_cast<QByteArray &>(message))。
});
更新:即使你可以用這種方式將constness拋開,也不意味著這樣做是個好主意:) 正如其他答案中所指出的,由于Qt的隱式共享機制,沒有對未改變的QByteArray進行資料復制。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/327635.html
標籤:
