如何设计一个安全管理自己生命周期的QObject

时间:2018-04-25 09:48:11

标签: c++ qt memory-management memory-leaks raii

我正在实现一个类Exporter来执行一些导出操作。该类派生自QObject。我想从类C(C :: triggerExport)的const函数创建一个指向堆上该类的指针。我无法创建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 :(得分:0)

由于您没有从triggerExport返回导出器指针,因此您无需担心。

允许对象在C ++中删除自身。因此,只要您在此之后不对会员执行任何操作,您就可以在完成后致电delete this;

也可以使用deleteLater(),只是在事件循环再次运行之前不会销毁对象。 Exporter必须从QObject派生出来。

如果决定从Exporter派生QWidget,您可以设置Qt::WA_DeleteOnClose标志,Qt会在窗口小部件关闭后处理销毁。

答案 1 :(得分:0)

如果我已正确理解,请检查以下解决方案:

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



    };

答案 2 :(得分:0)

  

我无法创建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();
}