2010-04-26 4 views
2

У меня есть класс, глядя, как это:Как правильно удалить экземпляр QProcess?

class FakeRunner : public QObject 
{ 
    Q_OBJECT 
private: 
    QProcess* proc; 
public: 
    FakeRunner(); 
    int run() 
    { 
     if (proc) 
      return -1; 
     proc = new QProcess(); 
     QStringList args; 
     QString programName = "fake.exe"; 

     connect(comp, SIGNAL(started()), this, SLOT(procStarted())); 
     connect(comp, SIGNAL(error(QProcess::ProcessError)), this, 
       SLOT(procError(QProcess::ProcessError))); 
     connect(comp, SIGNAL(finished(int, QProcess::ExitStatus)), this, 
       SLOT(procFinished(int, QProcess::ExitStatus))); 

     proc->start(programName, args); 

     return 0; 
    }; 

private slots: 
    void procStarted() {}; 
    void procFinished(int, QProcess::ExitStatus) {}; 
    void procError(QProcess::ProcessError); 
} 

С «fake.exe» не существует в моей системе, прок выдает сигнал ошибки(). Если бы я справиться с этим, как следующий, моя программа падает:

void FakeRunner::procError(QProcess::ProcessError rc) 
{ 
    delete proc; 
    proc = 0; 
} 

Он хорошо работает, хотя, если я не удалить указатель. Итак, вопрос в том, как (и когда) я должен удалить указатель на QProcess? Я считаю, что я должен удалить его, чтобы избежать утечки памяти. FakeRunner :: run() может вызываться много раз, поэтому утечка, если она есть, будет расти.

Спасибо!

ответ

8

Вы не можете удалить QObject экземпляр внутри слота, который подключен к сигналу в этом случае, используя обычный оператор удаления. Это связано с тем, что если сигнал и слот соединены с использованием прямого соединения, то слот фактически вызывается из реализации сигнала, сделанного moc. Это похоже на попытку delete this; изнутри члена класса. Существует решение QObject::deleteLater(). Объект будет удален в цикле событий Qt внутри функции обработки событий. Поэтому вам нужно позвонить proc->deleteLater() в ваш случай.

И вам не нужно отключать сигнал от слота, так как Qt делает это автоматически при удалении QObject.

+0

Я вижу. Безопасно ли обнулить указатель после вызова proc-> deleteLater() или использовать другой метод для определения того, существует ли процесс (я проверяю это в начале функции run(), чтобы избежать дублирования процессов)? – Kopfschmerzen

+0

Вы можете безопасно аннулировать указатель после deleteLater(). – VestniK

Смежные вопросы