Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt Общие вопросы _ [РЕШЕНО] Как передать слоту параметр по ссылке ?

Автор: Diem 10.3.2009, 15:32

Есть класс X для примера:
////////////////////// Файл x.h //////////////////////

#ifndef X_H
#define X_H
#include <QtDebug>
class X : public QObject
{
    Q_OBJECT
public:
    X(QObject *parent = 0);
public slots:
    void exampleSlot(QList<int> list);

signals:
    void exampleSignal(QList<int> list);
};
#endif // X_H

////////////////////// Файл x.cpp //////////////////////
#include"x.h"
X::X(QObject *parent)
    : QObject(parent)
{
    QList<int> list;
    list.append(1);
    qDebug() << "value before slot: " << list;
    connect(this, SIGNAL(exampleSignal(QList<int>)), this, SLOT(exampleSlot(QList<int>)));
    emit exampleSignal(list);
    qDebug() << "value after slot: " << list;
}
void X::exampleSlot(QList<int> list) {
    list.append(2);
    qDebug() << "value in slot: " << list;
}

////////////////////// Файл main.cpp //////////////////////
#include <QApplication>
#include "x.cpp"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    X x;
    return app.exec();
}

////////////////////// Вывод //////////////////////
Запуск...
value before slot: (1)
value in slot: (1, 2)
value after slot: (1)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Как сделать чтоб в выводе я получил "value after slot: (1, 2)" ?

 x.zip ( 811 байт ) : 119
 

Автор: kwisp 10.3.2009, 15:36

указатель либо ссылка

Автор: Diem 10.3.2009, 15:40

Ну как бы это очевидно.
Но я с c++ дело ооочень давно не имел, Все варианты перепробовал. Либо несовместимость типов либо ещё хрень какая.
Пожалуйста если можно на этом примере * и & раставить ? :unsure:

Автор: Litkevich Yuriy 10.3.2009, 15:42

так и пиши ссылку:
void exampleSlot(QList<int> &list);

Цитата(Diem @ 10.3.2009, 18:32) *
connect(this, SIGNAL(exampleSignal(QList<int> &)), this, SLOT(exampleSlot(QList<int>&)));

и сигнал соответственно тоже с сылкой:
void exampleSignal(QList<int> &list);

Автор: LE0N 10.3.2009, 15:46

А почему не * ?
На сколько я знаю, подход с & плохо пахнет ?

Автор: Litkevich Yuriy 10.3.2009, 15:47

Цитата(LE0N @ 10.3.2009, 18:46) *
На сколько я знаю, подход с & плохо пахнет ?
например?

Автор: Diem 10.3.2009, 15:49

Блин совсем запарился.
Всё верно, перепробывав все варианты забыл что и connect должен быть такого вида:
connect(this, SIGNAL(exampleSignal(QList<int>&)), this, SLOT(exampleSlot(QList<int>&)));

Спасибо.

Автор: kwisp 10.3.2009, 15:51

Цитата(LE0N @ 10.3.2009, 15:46) *
А почему не * ?

ну сделай указатель точно так же.



Цитата(Diem @ 10.3.2009, 15:49) *
Блин совсем запарился.
Всё верно, перепробывав все варианты забыл что и connect должен быть такого вида:

а в консольку не смотрим там небось предупреждение что таких сигналов и слотов нет....

Автор: LE0N 10.3.2009, 15:54

Да просто перехожу с СИ, на СИ++, читаю попутно Страуструпа, и именно там этот подход называют "гнилым".

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

Автор: Litkevich Yuriy 10.3.2009, 16:17

LE0N, на самом деле замечание было верным, но без понимания причин. предпочтительным является такой подход:
1) Если аргумент изменяется в вызываемой функции, то лучше использовать указатель, т.к. при передачи значения это будет видно:
http://wiki.crossplatform.ru/index.php/Designing_Qt-Style_C%2B%2B_APIs#.D0.A3.D0.BA.D0.B0.D0.B7.D0.B0.D1.82.D0.B5.D0.BB.D0.B8_.D0.B8.D0.BB.D0.B8_.D1.81.D1.81.D1.8B.D0.BB.D0.BA.D0.B8.3F
2) если аргумент не изменяется, то лучше использовать ссылки, НО константные:
void exampleSlot(const QList<int> &list);

Цитата(kwisp @ 10.3.2009, 18:51) *
а в консольку не смотрим там небось предупреждение что таких сигналов и слотов нет....
скорее всего он даже незнает о такой возможности Qt (добавить в файл проекта строчку: CONFIG += console, тогда Qt будет о многих неровных местах сама сообщать)

Автор: kwisp 10.3.2009, 16:19

Цитата(Litkevich Yuriy @ 10.3.2009, 16:17) *
скорее всего он даже незнает о такой возможности Qt (добавить в файл проекта строчку: CONFIG += console,

Цитата(Diem @ 10.3.2009, 15:32) *
////////////////////// Вывод //////////////////////
Запуск...
value before slot: (1)
value in slot: (1, 2)
value after slot: (1)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

:)

Автор: Litkevich Yuriy 10.3.2009, 16:38

kwisp, нда... ты прав :)

Автор: Diem 10.3.2009, 16:42

Такой подход у меня вызван тем, что есть конкретная задача:
Имеется tcp сервер (QTcpServer)
В нем периодически создаются экзэмпляры класса (буду именновать Y)
на каждый сигнал readyRead() срабатывает слот, который обрабатывает http хидеры и в зависимости от них вызывает нужную функцию.
Одна из функций посылает сигнал c параметрами из http заголовка (params) + передаёт локальную переменную (list) по ссылке, на этот сигнал реагируют слоты всех эземпляров класса Y.
И в зависимости от params либо всё игнорируют либо добавляют в list нужные данные.
Потомlist переводится в json и идёт в ответ браузеру. const Type& var конечно в таком случае не прокатит.
Так же при создании каждого экземпляра класса Y запускается QTimer при timeot() которого этот экземпляр и удаляется из памяти.

Так вот у меня вопрос: возможно ли создать что-то типа QMap<int, *MyClass>
что бы опрашивать в цикле, не все, а только те экземпляры Y которые мне нужно ?

Автор: kwisp 10.3.2009, 16:46

Цитата(Diem @ 10.3.2009, 16:42) *
QMap<int, *MyClass>

такое нельзя
можно
QMap<int, MyClass*>
помни мэп работает с копиями элементов.

Зы. модератор будет шуметь, потому что надо на каждый вопрос тему создавать а не раскручивать с одного вопроса ....:)

Автор: Litkevich Yuriy 10.3.2009, 16:47

Цитата(Diem @ 10.3.2009, 19:42) *
возможно ли создать что-то типа QMap<int, *MyClass>
а что тебя в этой записи смущает?

Автор: Diem 10.3.2009, 16:54

QMap<int, *MyClass> - выдаёт ошибку

Цитата
ошибка: `*' не может присутствовать в константном выражении

А QMap<int, MyClass*> - работает, спасибо.
Да за оффтоп sorry.

Автор: Litkevich Yuriy 10.3.2009, 16:59

я думаю вопрос поставленный в заголовке темы раскрыт полностью. И тему можно закрыть?

Автор: Diem 10.3.2009, 17:04

Да, конечно.

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)