qt 中不要让 lambda 槽函数捕获信号源对象的共享指针

错误示例

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

你可能感兴趣的:(qt,开发语言)