【发布时间】:2020-02-28 02:57:21
【问题描述】:
我对信号槽机制有疑问,可能是 QSharedPointer 实际上有问题,因为智能指针对我来说是新的。
对上下文的一点解释:
TCPAssociation 是 LANAssociation 的子类。 TCPClient 是 LANClient 的子类。 LANClient 有保护的QSharedPointer<LANAssociation> connection 变量,TCPClient 有私有的QSharedPointer<TCPAssociation> conn;两者都指向在覆盖的纯虚函数中创建的同一个对象,如下所示:
void TCPClient::startNewConnection(const QHostAddress &address)
{
conn.clear();
connection.clear();
conn = QSharedPointer<TCPAssociation>(new TCPAssociation(address, port, QString("Client %1").arg(hostId())));
Q_ASSERT(conn);
Q_ASSERT(connect(conn.data(), &LANAssociation::started, this, &LANClient::assoc_started, Qt::UniqueConnection));
connection = conn.staticCast<LANAssociation>();
Q_ASSERT(connection);
conn->start();
//TCPAssociation::start() { doStuff(); emit started(); }
}
代码在调试模式下的 Windows 10 上运行良好。在 Linux 的发布模式下,永远不会调用 LANClient::assoc_started。
现在我在 Windows 上运行我的服务器应用程序(上面的函数来自客户端应用程序),我可以看到另一个插槽在发布时没有被调用,但在调试中工作得很好:
void ThreadController::init(ThreadWorker *worker)
{
worker->moveToThread(&workerThread);
Q_ASSERT(connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater, Qt::UniqueConnection));
Q_ASSERT(connect(this, &ThreadController::operate, worker, &ThreadWorker::doWork, Qt::UniqueConnection));
Q_ASSERT(connect(worker, &ThreadWorker::finished, this, &ThreadController::finished, Qt::BlockingQueuedConnection));
doConnects(worker);
workerThread.start();
}
*worker 指向ThreadWorker 的子类。 ThreadWorker::doWork() 是虚函数。它是在调试中调用的,而不是在发布时调用的。我通过将doWork() 设为纯虚拟来修复它——现在它在调试和发布中都被调用了。
我也有QTcpSocket 和QUdpSocket 对象不发射connected() 或readyRead() 的问题。现在我明白这可能是因为我使用QSharedPointer<QAbstractSocket> 来管理它们,但是:
为什么调试和发布有区别?如何正确地做?
我应该停止使用继承还是共享指针?
- 为什么没有发出
TCPAssociation::started()?LANClient::assoc_started也不是虚函数。
【问题讨论】:
-
我觉得可以尝试在Q_ASSERT宏之外调用connect方法。根据配置,它可能永远不会被调用。
标签: c++ qt qt5 smart-pointers qsharedpointer