错误示例
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
,因为槽函数只有在信号源对象存活时才会被调用,不会引用已经析构了的信号源对象。直接使用裸指针性能更好。