Search code examples
qtqobjectvirtual-destructor

How to prevent a child from being deleted during deleteChildren() in Qt?


I have a logging interface that allows user to subclass a Logger and override the log() virtual function so users can create their own loggers. There is a manager that keeps track of all the registered logging methods (i.e. Console, syslog, Widget, etc.)

I've created a QListWidget Logger that shows logs. Unfortunately it's owned by the logging manager and since it's a QObject, it's also a child of the MainWindow. This results in two objects trying to delete it upon aplication close.

The first time around the QObjects->deleteChildren() gets called and it deletes it. Then the Loggin gmanager tries again and CRASH.

How can I prevent a specific QObject from being destroyed during deleteChildren()? Is that a bad idea?


Solution

  • You can't exclude a child from deletion, and if you could, that'd be a bad idea. In the QObject hierarchy, the child is owned by the parent. That's one of the main purposes of the parent-child relationship. I don't see why you should want a parent-child relationship without the deletion.

    Possibilities:

    1. Make it a child of the logging manager
    2. Don't give it a parent at all and let the logging manager delete it
    3. Don't give it a parent at all and use QSharedPointer/std::shared_ptr (the latter in C++11), managing it by using QSharedPointer instances int mainwindow and logger.

    Without knowing the code, I'd say the mainwindow shouldn't mess with the logger, so I would move the ownership completely to the manager.

    Also, I don't see a reason why the usual Logger interface should inherit from QObject at all, so I'd consider removing that inheritance completely (which leaves the "owned solely by Logging manager" and QSharedPointer options).