LINUX.ORG.RU

История изменений

Исправление ckotinko, (текущая версия) :

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

ты пишешь c одной стороны сигнал

void mysig(void * arg1, int arg2, double arg3)
с другой слот
void myslot(void * arg1, int arg2)
как происходит их соединение?

в общем случае, аргументы копируются, то есть можешь считать, что создается вот такая структура(в реальности немного не так, но пофиг)

struct args_for_signal_mysig : some_common_struct_for_sigs {
   void * arg1;
   int      arg2;
   double arg3;

   void * pargs[3];
};
и создается:
void mysig(void * arg1, int arg2, double arg3) {
   void * args = new args_for_signam_mysig;
   args->arg1 = arg1;
   args->arg2 = arg2;
   args->arg3 = arg3;
вот где твои параметры будут копироваться
   args->pargs[0] = &args->arg1;
   args->pargs[1] = &args->arg2;
   args->pargs[2] = &args->arg3;
   send_signal_somehow(args, args->pargs, 3);
в реализации mysig идет проверка, что у сигнала нет отложеных (queued) получателей. если их нет, то массив указателей соберут прямо из аргументов, минуя копирование. А на принимающей,
void myclass::dispatch_signal(QObject * sender, int signal_id, void ** pargs, int count) {
вот этот pargs - он как раз массив ранее заполненых аргументов. в сгенереном mocом файле будет switch по signal_id, а в нем, будут вызываться конкрентые функции, которым на вход будет подаваться что-то то такое:
case 100500:
   if (count >= 2)
      this->myslot(*reinterpret_cast<void*>(pargs[0]), 
                          *reinterpret_cast<int*>(pargs[1]));

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

конкретно в твоем случае если соединение только прямое, то этап копирования в самом сигнале будет пропущен и массив указателей соберут прямо из аргументов. если соединение не прямое, то копирование произойдет, при этом QString& будет низведен до QString, который станет копией и именно на него будет передан указатель.

указатель же на ссылку = ссылке. они в принципе одно и то же только по разному пишутся.

Исходная версия ckotinko, :

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

ты пишешь c одной стороны сигнал

void mysig(void * arg1, int arg2, double arg3)
с другой слот
void myslot(void * arg1, int arg2)
как происходит их соединение?

в общем случае, аргументы копируются, то есть можешь считать, что создается вот такая структура(в реальности немного не так, но пофиг)

struct args_for_signal_mysig : some_common_struct_for_sigs {
   void * arg1;
   int      arg2;
   double arg3;

   void * pargs[3];
};
и создается:
void mysig(void * arg1, int arg2, double arg3) {
   void * args = new args_for_signam_mysig;
   args->arg1 = arg1;
   args->arg2 = arg2;
   args->arg3 = arg3;
вот где твои параметры будут копироваться
   args->pargs[0] = &args->arg1;
   args->pargs[1] = &args->arg2;
   args->pargs[2] = &args->arg3;
   send_signal_somehow(args, args->pargs, 3);
в реализации mysig идет проверка, что у сигнала нет отложеных (queued) получателей. если их нет, то массив указателей соберут прямо из аргументов, минуя копирование. А на принимающей,
void myclass::dispatch_signal(QObject * sender, int signal_id, void ** pargs, int count) {
вот этот pargs - он как раз массив ранее заполненых аргументов. в сгенереном mocом файле будет switch по signal_id, а в нем, будут вызываться конкрентые функции, которым на вход будет подаваться что-то то такое:
case 100500:
   if (count >= 2)
      this->myslot(*reinterpret_cast<void*>(pargs[0]), 
                          *reinterpret_cast<int*>(pargs[1]));

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