Подтвердить что ты не робот

Const-ref при отправке сигналов в Qt

Это то, что я никогда не получал с const-ref, и я очень надеюсь, что кто-то может объяснить это мне.

При вызове функции внутри другой функции я получаю, что const-ref - лучший способ передать объекты стека, которые я не планирую вмешиваться. Например:

void someInnerFunction(const QString& text) {
    qDebug() << text;
}

void someFunction() {
    QString test = "lala";
    ....
    someInnerFunction(test);
}

До сих пор так хорошо, я думаю. Но как насчет сигналов? Разве нет никакого риска, связанного с передачей ссылки? Даже если он const. Похоже, я читал все документы об const-ref, но все же считаю, что это немного рискованно, так как я понимаю это как "отправку ссылки на объект и сохранение const". Что, если объект, на который он ссылается, выходит за рамки?

Например:

void someFunction() {
    connect(this, SIGNAL(someSignal(const QString&)), this, SLOT(someSlot(const QString&)));

    QString test = "lala";
    emit someSignal(test);

    // doesnt test go out of scope here? and since im not using queued connection the QString object doesnt get copied. 
}

void someSlot(const QString& test) {
    qDebug() << test; // will this work?
}

Что на самом деле происходит здесь? Я часто использую const-ref для вызова функций, где я просто хочу получить доступ к объекту, но не изменять его. Но как насчет сигналов? Большинство сигналов, похоже, содержат константный рефлекс в Qt doc, но как это работает?

4b9b3361

Ответ 1

В соответствии с этим ответом Qt просто заменяет ссылки const на копии.

EDIT: По-видимому, это не всегда случай... Я просто сделал базовую тестовую программу с одним потоком, и ссылка была передана правильно. Его константа оставалась неповрежденной. В любом случае, да, вам нужно опасаться, что переменная выходит из области видимости, плюс вы не можете отправлять ссылки по потокам таким образом. Если вы это сделаете, будут переданы только копии.

Чтобы ответить на вопросы в комментариях к вашему примеру, да, он будет работать независимо от того, является ли это прямым или поставленным в очередь. Если это прямое соединение, оно будет работать, потому что someSlot() будет выполнено до завершения someFunction(); если это очередное соединение, оно будет работать, потому что test будет скопировано вместо переданного по ссылке.

Ответ 3

В Qt при испускании сигнала, который подключен к слоту или слотам, он приравнивается к синхронному вызову функции... если вы не настроили свои сигналы и слоты для использования подключений в очереди, то это асинхронный вызов и вы должны быть осторожны при передаче данных стека и должны передавать копию, как бы передавая данные в другой поток.