4

我有一个发出 3 个不同信号的对象,我想传输这些信号并删除它们的发送者。该对象位于将充当这些信号的发射器的另一个对象中。

通常我会这样:

void SomeClass::someSideFunction() {
    Request* request = _StorageProvider.insert("somedata");

    connect(request, SIGNAL(succeded()),        this, SLOT(handleSucceded()));
    connect(request, SIGNAL(failed()),          this, SLOT(handleFailed()));
    connect(request, SIGNAL(alreadyExists()),   this, SLOT(handleAlreadyExists()));
}

void SomeClass::handleSucceded() {
    Request* request = qobject_cast<Request*>(sender());
    if(request != NULL) request ->deleteLater();
    emit succeded();
}

void SomeClass::handleFailed() {
    Request* request = qobject_cast<Request*>(sender());
    if(request != NULL) request ->deleteLater();
    emit failed();
}

void SomeClass::handleAlreadyExists() {
    Request* request = qobject_cast<Request*>(sender());
    if(request != NULL) request ->deleteLater();
    emit alreadyExists();
}

有没有更好的方法来做到这一点?即使“请求”是 storageProvider 的子项,但仍有许多请求正在进行,我只需要等待删除它们,直到父项死亡。

我在想这样的解决方案:

connect(request, SIGNAL(succeded()),        this, SIGNAL(succeded()));
connect(request, SIGNAL(failed()),          this, SIGNAL(failed()));
connect(request, SIGNAL(alreadyExists()),   this, SIGNAL(alreadyExists()));
connect(request, SIGNAL(succeded()),        this, SLOT(memoryHnadler()));
connect(request, SIGNAL(failed()),          this, SLOT(memoryHnadler()));
connect(request, SIGNAL(alreadyExists()),   this, SLOT(memoryHnadler()));

如果存在,内存处理程序将删除发送者。这种方法有什么缺点,什么可能更好?

请注意,对象在完成时只会发出这些信号之一!

4

2 回答 2

3

An option is to have the request schedule its own deletion using QObject::deleteLater(). Like this:

void Request::emitSucceeded() {
    emit succeeded();
    deleteLater();
}

void Request::emitFailed(int errorCode, const QString& errorString ) {
    m_errorCode = errorCode;
    m_errorString = errorString;
    emit failed();
    deleteLater();
}

For instance, KDELib's base class for asynchronous operations, KJob, is using this pattern (unless explicitly disabled via setAutoDelete(false)).

于 2012-05-14T07:43:41.450 回答
2

我看不出您的第二种方法有任何不利之处。Qt 将首先发送信号,然后是内存处理程序,因为它的执行顺序与您声明连接的顺序相同。

内存处理程序必须是唯一删除 Request 对象的处理程序。

另一种方法是使用 Request 对象作为参数发出信号,然后依靠用户槽删除它们。但是如果没有声明用户槽,你将保持内存增长......

于 2012-05-14T07:01:30.747 回答