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

メモリハンドラーが送信者を削除する場所(存在する場合)。このアプローチの欠点は何であり、より良いものは何でしょうか?

オブジェクトは、実行時にこれらの信号の1つのみを放出することに注意してください。

4

2 に答える 2

3

オプションとして、QObject :: deleteLater()を使用してリクエストに独自の削除をスケジュールさせることができます。このような:

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

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

たとえば、非同期操作のKDELibの基本クラスであるKJobは、このパターンを使用しています(setAutoDelete(false)で明示的に無効にされている場合を除く)。

于 2012-05-14T07:43:41.450 に答える
2

私はあなたの2番目のアプローチのマイナス面を見ることができません。Qtは、接続を宣言するのと同じ順序で実行されるため、最初にシグナルを送信し、後でメモリハンドラーを送信します。

リクエストオブジェクトを削除するのはメモリハンドラだけである必要があります。

もう1つのアプローチは、Requestオブジェクトを引数として信号を送信し、ユーザースロットに依存して信号を削除することです。ただし、ユーザースロットが宣言されていない場合は、メモリが増え続けます...

于 2012-05-14T07:01:30.747 に答える