0

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);
scopchanov
  • 7,966
  • 10
  • 40
  • 68
arc_lupus
  • 3,942
  • 5
  • 45
  • 81
  • 2
    If you manage a lifetime of your object with Qt (via `QObject::deleteLater`) - you don't need a `std::unique_ptr`. There is a logic conflict. You need to choose, how do you want to delete your object. – Dmitry Sazonov Jan 29 '18 at 13:19
  • 1
    Just out of curiosity, what will you gain by making the slave as a constructor only class and removing the d'ctor? – PRIME Jan 29 '18 at 13:20
  • I propose you to look at `QPointer` to keep `serial_worker` instance. Connect it to your thread finished signal and delete it directly in destructor of `serial_controller_master`. But be carefull with multithreading. – Dmitry Sazonov Jan 29 '18 at 13:21
  • @PRIME: Maybe I am a bit confused, but earlier (https://stackoverflow.com/questions/47883862/implement-assignment-operator-for-class-with-large-amount-of-elements/47886700#comment82772756_47886700) I was lectured about using an destructor too often, thus I tried to remove it in this case, too – arc_lupus Jan 29 '18 at 13:25
  • Not having a d'ctor for this class would be counter intiutive. I agree with the point of @DmitrySazonov – PRIME Jan 30 '18 at 04:17

1 Answers1

2

1)Anyway you need do

serial->close();

at the end, so anyway you need destructor.
2)If you need moveToThread with QScopedPointer example look here.