Почему этот пример Qt работает с адресами вместо самих объектов и функций? И без ключевых слов SLOT / SIGNAL? - PullRequest
1 голос
/ 10 июня 2019

Я встречал этот код в документации Qt:

Counter a, b;

QObject::connect(&a, &Counter::valueChanged,

                 &b, &Counter::setValue);

a.setValue(12);     // a.value() == 12, b.value() == 12
b.setValue(48);     // a.value() == 12, b.value() == 48

Почему существуют символы & перед a и b и перед функциями?a является излучающим объектом (обеспечивает сигнал), а b является принимающим объектом (имеет слот), так почему их адрес берется здесь, вместо того, чтобы просто использовать сами объекты (& принимает адрес объекта, если я неошибаюсь)?В других примерах Qt это не так (адрес не используется, сами объекты)

Я не слишком уверен, как вызывается функция & before (т.е. Counter :: valueChanged и Counter ::setValue) работа ... Я думаю, что это заставляет их вернуться по ссылке, но я не уверен, насколько это важно здесь.

Наконец, почему нет ключевых слов SLOT и SIGNAL?Разве это не должны быть SIGNAL (Counter :: valueChanged) и SLOT (Counter :: setValue)?Опять же, это то, что я видел в других примерах QObject: connect, и этот пример не имеет смысла для меня.

Любая помощь приветствуется!

1 Ответ

3 голосов
/ 10 июня 2019

Посмотрите на это:

Counter a, b; // objects created on the stack, they are not pointers

// get the addresses of the objects and assign them as pointers.
Counter *aPointer = &a;
Counter *bPointer = &b;

Следующее не будет компилироваться, потому что a и b не являются указателями, а QObject connect ожидает указатели на экземпляры классов, которые наследуются от QObject.

QObject::connect(a, &Counter::valueChanged, b, &Counter::setValue);

Следующее будет скомпилировано, потому что вы предоставляете указатели:

QObject::connect(aPointer, &Counter::valueChanged, bPointer, &Counter::setValue);

Точно так же это работает, потому что вы берете адрес (он же указатель) объектов:

QObject::connect(&a, &Counter::valueChanged, &b, &Counter::setValue);

Это, мы надеемся, объясняет & перед объектами. Затем перед именами функций стоят & s . Это синтаксис указателя на функцию-член:

&Counter::valueChanged 

Имя класса (Counter), к которому добавляются :: и имя функции-члена (valueChanged), с предшествующим & .

Это элемент указателя, который предоставляется в качестве первого аргумента в этом случае. Этот называется сигналом. Под капотом Qt зовет их вместе.

QObject *sender = &a;
std::function<void()> signal = std::bind(&Counter::valueChanged,sender);
...
signal(); // the function is called here

То же самое происходит со слотом.

Наконец, используются макросы SIGNAL () и SLOT ()

Надеюсь, это прояснит некоторые ваши вопросы.

...