2017-02-12 16 views
2

В рамках qt большинство сигналов библиотеки и слотов используют указатели в качестве параметров. Мне было интересно: если я создам «структуру» сигнального слота, которая принимает ссылку как параметр вместо указателя, будет ли скопирован весь параметр или всего 4 байта (32-разрядная система), как в обычной ссылке на C++?Qt-сигнал и слоты: копируются ли ссылочные аргументы?

Я спрашиваю об этом, потому что я заметил что-то, когда создаю методы сигнала/слота с эталонным параметром. Когда я тогда connect их, механизм автозаполнения в QTCreator не намекает мне со ссылочными параметрами, как он будет делать с параметрами указателя. Он намекает мне на регулярный параметр. Например:

создать сигнал и слот:

... 
signals: 
    void mySignal(int& parameter); 
private slots: 
    void on_mySignal(int& parameter); 

Я затем попытаться соединили их и Qt оленья кожа добавить & для справки в параметре:

... 
connect(this, SIGNAL(mySignal(int)), this, SLOT(on_mySignal(int))); 

я должен вручную изменить на :

connect(this, SIGNAL(mySignal(int&)), this, SLOT(on_mySignal(int&))); 

Таким образом, мне интересно, действительно ли ссылка работает с сигналами/с много? Буду признателен всем за помощь.

+1

Ваше помещение ошибочно. Регулярные ссылки на C++ не имеют размера, поскольку они не являются объектами. Вы не можете, например, использовать 'sizeof' для получения размера ссылки. Также вы должны прекратить использование устаревшего синтаксиса сигнала/слота. Правильный синтаксис - это «connect (this, & Class :: mySignal, this, & Class :: on_mySignal)», который позволяет вам не беспокоиться об этом. – nwp

+0

Я понимаю, спасибо. Но чтобы ответить на главный вопрос: при использовании сигналов/слотов со ссылкой, большой объем данных копируется? – Bremen

+0

Я бы ожидал копию 'int', даже если вы указали' int & '. Вы можете проверить это, назначив аргумент в слоте и посмотрите, изменился ли параметр, который вы передали. – nwp

ответ

5

Если вы отправляете и получаете ссылку в том же потоке, по умолчанию копия не будет сделана. Если вы сделаете что-нибудь еще, включая отправку/получение значения или отправку ссылки на другой поток, будет сделана одна, две или даже три копии.

Что происходит, зависит от типа подключения и заверений. QT должен знать, что ссылки остаются действительными в результате вызова. Прямое соединение в одном потоке разрешает простой вызов функции, поэтому очень мало может произойти с базовыми данными. Однако очередь в очереди не гарантирует никаких гарантий, когда вызов действительно произойдет, поэтому QT сделает копии для сохранения целостности данных. QT неявно ставит в очередь сигналы, пересекающие границы потоков.

Если какая-либо сторона имеет значение pass-by-value, то QT копирует данные, чтобы не влиять на состояние базового объекта.

Для получения дополнительной информации, have a look at this blog post.

+1

Йохан, вы не правы. Копирование не зависит от потоков, это зависит от типа подключения слота. Даже в тех же аргументах потока ref копируются в случае очереди в очереди. Прочтите документацию Qt: http://doc.qt.io/qt-5/qt.html#ConnectionType-enum –

+0

Дмитрий, спасибо. Добавлено уточнение. – Johan