简体   繁体   中英

Qt slots are not called in release mode and I blame QSharedPointer

I have a problem with signal-slot mechanism, may be that it's actually a problem with QSharedPointer as smart pointers are new to me.

A little explanation of the context: TCPAssociation is child class of LANAssociation . TCPClient is child class to LANClient . LANClient has protected QSharedPointer<LANAssociation> connection variable, TCPClient has private QSharedPointer<TCPAssociation> conn ; both pointing to the same object being created in overriden pure virtual function shown below:

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(); }
}

The code works on Windows 10 in debug mode just fine. In release mode on Linux, LANClient::assoc_started is never called.

Now I ran my server application (above function is from a client app) in release on Windows and I can see another slot not being called in release but working just fine in debug:

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 points to child class of ThreadWorker . ThreadWorker::doWork() is virtual function. It was called in debug, not in release. I fixed it by making doWork() pure virtual - now it's called both in debug and release.

I have also problem with QTcpSocket and QUdpSocket objects not emitting connected() or readyRead() . Now I understand it's probably because I am using QSharedPointer<QAbstractSocket> to manage them, but:

  1. why the difference between debug and release? how to do it properly?

  2. Should I stop using inheritance or shared pointers?

  3. why TCPAssociation::started() is not being emitted? LANClient::assoc_started is also not a virtual function.

The expression inside the Q_ASSERT macro will not be evaluated in non-debug build configurations:

Q_ASSERT() is useful for testing pre- and post-conditions during development. It does nothing if QT_NO_DEBUG was defined during compilation.

https://doc.qt.io/qt-5/qtglobal.html#Q_ASSERT

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM