lundi 29 janvier 2018

Usage of std::unique_ptr when moving object to worker thread in QT

I am trying to update old code by removing class destructors. Now I got to the following code situation with a QT master and a QT slave (the slave is created, and moved to a second thread afterwards):
My slave was formerly written as

serial_controller_worker::serial_controller_worker(const QString &portname, int waitTimeout, int BaudRate, int numStopBits, bool parity, bool useParity, bool useHex)
{
    this->portName = portname;
    this->waitTimeout = waitTimeout;
    this->baudrate = BaudRate;
    this->numStopBits = numStopBits;
    this->useParity = useParity;
    this->parity = parity;
    this->useHex = useHex;
    this->serial = new QSerialPort(this);
    this->storage = "";
    this->delay_write = 0;
}

serial_controller_worker::~serial_controller_worker()
{
    if(this->serial->isOpen())
        this->serial->close();
    if(this->serial != NULL)
        delete this->serial;
}

and was called in the master as

serial_controller_worker *newWorker = new serial_controller_worker(portName, waitTimeout, BaudRate, numStopBits, parity, useParity, useHex);
newWorker->moveToThread(&workerThread);
this->Hex = Hex;
connect(&workerThread, &QThread::finished, newWorker, &QObject::deleteLater);
connect(this, &Serial_port_library::newTransaction, newWorker, &serial_controller_worker::transaction);
connect(this, &Serial_port_library::connect_now, newWorker, &serial_controller_worker::connectToSerial);
connect(newWorker, &serial_controller_worker::response, this, &Serial_port_library::response_slot);
connect(newWorker, &serial_controller_worker::error_Val, this, &Serial_port_library::connectError);
workerThread.start();
emit this->connect_now();

Now I would like to transfer the slave to a constructor-only class, thus removing the destructor in the slave class. Nevertheless I still have to keep the destruction functions. Thus I created a new function for that:

void serial_controller_worker::delete_serial_controller_worker()
{
    if(this->serial->isOpen())
        this->serial->close();
    if(this->serial != NULL)
        delete this->serial;
}

and created a std::unique_ptr with a custom destructor function:

struct WorkerFree
{
  void operator() (serial_controller_worker *p) const { p->delete_serial_controller_worker(); }
};

class serial_controller_master{
    private:
        std::unique_ptr<serial_controller_worker, WorkerFree> serial_worker;
    public:
        serial_controller_master();
}

serial_controller_master::serial_controller_master()
{
    serial_worker.reset(serial_controller_worker(portName, waitTimeout, BaudRate, numStopBits, parity, useParity, useHex));
    serial_worker->moveToThread(&workerThread);
    this->Hex = Hex;
    connect(&workerThread, &QThread::finished, serial_worker, &QObject::deleteLater);
}

How can I tell QT to use my "destructor" when calling QObject::deleteLater() instead of trying to find another destructor, and how do I use the connect-calls later correctly? Currently I get errors like

error: no matching function for call to ‘Serial_port_library::connect(QThread*, void (QThread::*)(QThread::QPrivateSignal), std::unique_ptr<serial_controller_worker, WorkerFree>&, void (QObject::*)())’
     connect(&workerThread, &QThread::finished, serial_worker, &QObject::deleteLater);

Aucun commentaire:

Enregistrer un commentaire