錯誤示例
std::shared_ptr<QSerialPort> serial{new QSerialPort{}};QSerialPort::connect(serial.get(),&QSerialPort::readyRead,[serial](){QByteArray receive_data = serial->readAll();std::cout.write(receive_data.data(), receive_data.size());});
這會直接導致共享指針循環引用。
QSerialPort 對象會儲存 lambda 槽函數,進而儲存了捕獲列表中的共享指針對象,而 QSerialPort 對象自己又是通過共享指針管理的。當外部釋放了 QSerialPort 對象的共享指針后,QSerialPort 對象內部的槽函數列表還持有一份 QSerialPort 的共享指針,導致引用計數無法歸 0, 進而導致內存泄漏。
正確示例
std::shared_ptr<QSerialPort> serial{new QSerialPort{}};QSerialPort *_raw_serial_ptr = serial.get();QSerialPort::connect(serial.get(),&QSerialPort::readyRead,[_raw_serial_ptr](){QByteArray receive_data = _raw_serial_ptr->readAll();std::cout.write(receive_data.data(), receive_data.size());});
應該創建一個裸指針,用值捕獲的方式直接捕獲裸指針。其實也沒必要使用 std::weak_ptr
,因為槽函數只有在信號源對象存活時才會被調用,不會引用已經析構了的信號源對象。直接使用裸指針性能更好。