Как разработать QObject, который безопасно управляет собственной жизнью - PullRequest
0 голосов
/ 25 апреля 2018

Я реализую класс Exporter для выполнения некоторых действий экспорта.Этот класс является производным от QObject.Я хочу создать указатель на этот класс в куче из константной функции класса C (C :: triggerExport).Я не могу создать unique_ptr как член класса C, так как я не могу изменить его из элемента triggerExport.

class Exporter
{
   void export()
   {
      // Do some initialization.... 
      // problem: if an exception is thrown here, the Exporter will never
      // be deleted
      QDialog * dialog = new QDialog();
      connect(dialog, SIGNAL(rejected()), SLOT(deleteLater());
   }
};

class C
{
  void triggerExport() const
  {
     //create new here
     Exporter * e = new Exporter;
     e->export();
  }
};

Как я могу спроектировать Exporter таким образом, чтобы он не вызывал утечек при наличии исключений?

Ответы [ 3 ]

0 голосов
/ 25 апреля 2018

Если я правильно понял, проверьте решение ниже:

class Exporter:public QDialog
    {
      signals:
        void closeDialog();
      protected:
         void closeEvent(QCloseEvent *event)
         {
          emit closeDialog();
          event->accept();
        } 

       void export()
       {
           //Do the stuff
       }
    };

    class C
    {
      Exporter * e=0;
     public slots:
       void deleteExporter()
         {delete e;
           e=0;
          }
      void triggerExport() 
      {
          if(e){return;}
         //create new here
         e = new Exporter;
         connect(Exporter,SIGNAL(closeDialog()),this,SLOT(deleteExporter()));
         e->export();
      }



    };
0 голосов
/ 25 апреля 2018

Я не могу создать unique_ptr в качестве члена класса C, поскольку не могу изменить его из члена triggerExport.

На самом деле вы можете, используя unique_ptr :: reset ()

Предполагается, что C содержит что-то вроде этого:

class C {
...
    void triggerExport();
private:
    std::unique_ptr<Exporter> exporter;
};

Затем вы можете написать triggerExport () так:

void C::triggerExport() {
    exporter.reset(new Exporter);
    exporter->export();
}
0 голосов
/ 25 апреля 2018

Поскольку вы не возвращаете указатель Exporter из triggerExport, вам не о чем позаботиться.

Объекту разрешено удалять себя в C ++. Поэтому, если после этого вы не выполняете никаких операций над участниками, вы можете просто позвонить delete this;, когда закончите.

Использование deleteLater() также возможно, только если объект не будет уничтожен до повторного запуска цикла обработки событий. И Exporter должен был бы быть выведен из QObject для этого.

Если вы решили получить Exporter из QWidget, вы можете просто установить флаг Qt::WA_DeleteOnClose, и Qt позаботится об уничтожении после закрытия виджета.

...