Russian Qt Forum
Ноябрь 27, 2024, 20:19 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 [3] 4 5 ... 8   Вниз
  Печать  
Автор Тема: Частный случай механизма сигнал-слот  (Прочитано 73863 раз)
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #30 : Февраль 21, 2011, 15:55 »

Обобщил решение))

Теперь при создании объекта signal в классе который будет его имитеть, нужно лишь указать один шаблонный аргумент - T_art:
Код
C++ (Qt)
class A : public ssc::trackable
{
public:
   A(){}
 
   ssc::signal<std::string> my_signal;  /* вот здесь указываем [b]только[/b]
                                                                тип передаваемого арг:  std::string */

 
   void run() {
       my_signal("Hello Word!");   // эмитем сигнал
   }
 
};
 


Соединятся сигнал может с любой функцией, представимой в виде:
Код
C++ (Qt)
   typedef T_return (T_receiver::*function_type_1)(T_arg);
   typedef T_return (T_receiver::*function_type_2)(const T_arg &);
   typedef T_return (T_receiver::*function_type_3)(T_arg) const;
   typedef T_return (T_receiver::*function_type_4)(const T_arg &) const;
 
 

Т.е. в дальнейшем всё как обычно:
Код
C++ (Qt)
class B : public ssc::trackable
{
public:
   B() {}
 
   void slot1(const std::string &str) {
       std::cout << "slot1, signal - " << str << std::endl;
   }
 
   int slot2(std::string str) const {
       std::cout << "slot2, signal - " << str << std::endl;
       return 123;
   }
};
 
int main()
{
   B *b = new B;
   A *a = new A;
 
   connect(a->my_signal, b, &B::slot1);
   connect(a->my_signal, b, &B::slot2);
 
   a->run();
 
   delete b;
   delete a;
 
   return 0;
}
 

Исходники прилагаются.
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #31 : Февраль 21, 2011, 16:50 »

И вновь обобщил решение))

Теперь с сигналом могут соединятся не только методы класса, но и обычные функции:

Код
C++ (Qt)
int my_func(const std::string &str) {
   std::cout << str << std::endl;
   return str.size();
}
 
class A
{
public:
 
   ssc::signal<std::string> my_signal;
 
   void run() {
       my_signal("Hello Word!");
   }
};
 
int main()
{
   B *b = new B;
   A *a = new A;
 
   connect(a->my_signal, b, &B::slot1);
   connect(a->my_signal, b, &B::slot2);
   connect(a->my_signal, my_function);  // Соединение с обычной функцией
 
   a->run();
 
   delete b;
   delete a;
 
   return 0;
}
 

Далее я изменил название основных классов:
Основным абстрактным классом соединения, предоставляющем интерфейс теперь является
Код
C++ (Qt)
template <class T_arg>
class base_connection
{
public:
   base_connection() {}
   virtual ~base_connection() {}
   virtual void operator() (const T_arg &) const = 0;
   virtual bool valid() const = 0;
};
 

вместо base_signal, что правильнее отражает суть и предназначение этого класса

Соответственно класс signal теперь содержит список всех своих соединений base_connection
Код
C++ (Qt)
std::list<base_connection<T_arg>* > _list;
 


Класс manager_connection переименован в mem_func_connection:
Код
C++ (Qt)
template <class T_receiver, class T_return, class T_arg>
class mem_func_connection : public base_connection<T_arg>
 

и предназначен для создания соединений с методами класса

Появился новый класс func_connection
Код
C++ (Qt)
template <class T_return, class T_arg>
class func_connection : public base_connection<T_arg>
 
перназначенный для создания соединения с обычными функциями

Соответственно появились версии перегруженных функций connection для соединения сигнала с обычными функциями.

Исходники приатачены, прошу потестить.


Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #32 : Февраль 22, 2011, 17:35 »

Решил дополнить функционал, добавив
1) функцию disconnect, которая бы разрывала соединение
2) В самом соединении connect, вначале проверять, есть ли в списке уже зарегистрированное такое же соединение и если есть, то не вносить его повторно в список.

Но столкнулся с маленькой проблемкой.  Суть которой в следующем:
Поскольку список соединений содержит указатели на объекты base_connection - предоставляющим интерфейс соединения, то манипуляции все происходят через его интерфейс.
Т.е. это означает, что я например, мог бы определить например функцию address в базовой реализации:
Код
C++ (Qt)
template <class T_arg>
class base_connection
{
public:
   base_connection() {}
   virtual ~base_connection() {}
   virtual void operator() (const T_arg &) const = 0;
   virtual bool valid() const = 0;
   virtual long address_obj() const = 0; /* Вот эта новая функция, которая, к примеру,  
                                                                  будет возвращать адрес объекта receivera */

   virtual long address_mem_func() const = 0; /* А это адрес функции (слота) */
};
 
 
Тогда я бы мог перед тем как добавить новое соединение в список, проверить использую пару новых функций не содержится ли уже в списке такое же соединение.

А вот пример реализации этих функция в mem_func_connection:
Код
C++ (Qt)
long mem_func_connection::address_obj() const
{
   return (long)_receiver; // _receiver - это указатель
}
long mem_func_connection::address_mem_func() const
{
   return (long)&_slot; /* _slot - принадлежитодному из 4 типов:
                                       typedef T_return (T_receiver::*_function_type_1)(T_arg); (N = 1, 2, 3, 4)
                                       typedef T_return (T_receiver::*_function_type_2)(T_arg) const;
                                       ...
*/

}
 


Но меня мучают сомнения в корректности реализации address_mem_func() const
Хотя формально всё работает..
Дело в том, что как выяснилось sizeof(long) и sizeof(function_type_N) (N = 1,2,3,4) различаются, причём последний в два раза больше чем размкер long.  

Как быть? Куда копать?
Спасибо за помощь)
« Последнее редактирование: Февраль 22, 2011, 17:44 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
brankovic
Гость
« Ответ #33 : Февраль 23, 2011, 16:34 »

2) В самом соединении connect, вначале проверять, есть ли в списке уже зарегистрированное такое же соединение и если есть, то не вносить его повторно в список.

Т.е. это означает, что я например, мог бы определить например функцию address в базовой реализации:

Надо же, проект цветёт и колосится! Наискосок просмотрел, похоже на полную победу сил разума.

Про connect, может вместо address сделать так:

Код
C++ (Qt)
 
template <typename T>
class base_connection
{
 virtual bool operator== (base_connection const &) const = 0;
};
 
template <typename T, typename Obj, typename Method>
class custom_connection : public base_connection <T>
{
  Obj *o;
  Method m;
 
  bool operator== (base_connection <T> const &b) const
  {
     custom_connection *c = dynamic_cast <custom_connection *> (&b);
     return c && c->o == o && c->m == m;
  }
};
 
 

если я правильно понял проблему..

P.S.: про шаред птр -- его трудно сделать полностью тред-сейф, но чтобы он стал не хуже бустовского, нужно заменить ++counter и --counter на атомарные ++ и --. В кьют это будет QAtomicInt, а в gcc есть __sync_fetch_and_add для такого.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #34 : Февраль 23, 2011, 16:48 »

2) В самом соединении connect, вначале проверять, есть ли в списке уже зарегистрированное такое же соединение и если есть, то не вносить его повторно в список.

Т.е. это означает, что я например, мог бы определить например функцию address в базовой реализации:

Надо же, проект цветёт и колосится! Наискосок просмотрел, похоже на полную победу сил разума.

Про connect, может вместо address сделать так:

Код
C++ (Qt)
 
template <typename T>
class base_connection
{
 virtual bool operator== (base_connection const &) const = 0;
};
 
template <typename T, typename Obj, typename Method>
class custom_connection : public base_connection <T>
{
  Obj *o;
  Method m;
 
  bool operator== (base_connection <T> const &b) const
  {
     custom_connection *c = dynamic_cast <custom_connection *> (&b);
     return c && c->o == o && c->m == m;
  }
};
 
 

если я правильно понял проблему..

P.S.: про шаред птр -- его трудно сделать полностью тред-сейф, но чтобы он стал не хуже бустовского, нужно заменить ++counter и --counter на атомарные ++ и --. В кьют это будет QAtomicInt, а в gcc есть __sync_fetch_and_add для такого.

Спасибо)) Это именно то что нужно Улыбающийся
Сейчас сделаем)
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #35 : Февраль 23, 2011, 21:15 »

Так, сделал по совету brankovic: определил оператор
Код
C++ (Qt)
template <class T_arg>
class base_connection
{
public:
   base_connection() {}
   virtual ~base_connection() {}
   virtual void operator() (const T_arg &) const = 0;
   virtual bool valid() const = 0;
   virtual bool operator==(base_connection<T_arg> *) const = 0;  // Вот этот оператор
};
 
И всё заработало, но.. Но работает только так:
Код
C++ (Qt)
class signal
{
public:
   signal() {}
   ~signal() {
       for (_iterator it = _list.begin(); it != _list.end(); it++) {
           delete *it;
       }
       _list.clear();
   }
 
   void operator() (const T_arg &arg) const {
       for (_const_iterator it = _list.begin(); it != _list.end(); it++) {
           if ((*it)->valid())
               (*it)->operator()(arg);
       }
   }
 
   template <class T1, class T2, class T3> friend class mem_func_connection;
   template <class T1, class T2> friend class func_connection;
 
private:
   std::list<base_connection<T_arg>* > _list;
   typedef typename std::list<base_connection<T_arg>* >::iterator _iterator;
   typedef typename std::list<base_connection<T_arg>* >::const_iterator _const_iterator;
 
   void connect(base_connection<T_arg> *c) {
       for (_iterator it = _list.begin(); it != _list.end(); it++) {
           if (c->operator ==(*it)) {  /* Вот здесь приходится явно вызывать operator==(...)
                                                         а если просто c == *it то не сработывает :(   Где подвох?
                                                         я сейчас немного не в состоянии думать))                   */

               delete c;
               return;
           }
       }
       _list.push_back(c);
   }
};
 


Вот полный код signal_slot.h
Код
C++ (Qt)
#ifndef SIGNAL_SLOT_H
#define SIGNAL_SLOT_H
 
#include <list>
#include "smart_ptr.h"
#include <iostream>
 
namespace ssc {
 
template <class T_arg>
class base_connection
{
public:
   base_connection() {}
   virtual ~base_connection() {}
   virtual void operator() (const T_arg &) const = 0;
   virtual bool valid() const = 0;
   virtual bool operator==(base_connection<T_arg> *) const = 0;
};
 
 
class trigger
{
public:
   trigger() : _flag(true) {}
   void set(bool flag) { _flag = flag; }
   bool get() const { return _flag; }
 
private:
   bool _flag;
};
 
class trackable
{
public:
   trackable() {
       spy = smart_ptr<trigger>(new trigger);
   }
   virtual ~trackable() {
       spy->set(false);
   }
   smart_ptr<trigger> spy;
};
 
template <class T_arg>
class signal
{
public:
   signal() {}
   ~signal() {
       for (_iterator it = _list.begin(); it != _list.end(); it++) {
           delete *it;
       }
       _list.clear();
   }
 
   void operator() (const T_arg &arg) const {
       for (_const_iterator it = _list.begin(); it != _list.end(); it++) {
           if ((*it)->valid())
               (*it)->operator()(arg);
       }
   }
 
   template <class T1, class T2, class T3> friend class mem_func_connection;
   template <class T1, class T2> friend class func_connection;
 
private:
   std::list<base_connection<T_arg>* > _list;
   typedef typename std::list<base_connection<T_arg>* >::iterator _iterator;
   typedef typename std::list<base_connection<T_arg>* >::const_iterator _const_iterator;
 
   void connect(base_connection<T_arg> *c) {
       for (_iterator it = _list.begin(); it != _list.end(); it++) {
           if (c->operator ==(*it)) {
               delete c;
               return;
           }
       }
       _list.push_back(c);
   }
};
 
template <class T_return, class T_arg>
class func_connection : public base_connection<T_arg>
{
public:
   typedef T_return (*function_type_1)(T_arg);
   typedef T_return (*function_type_2)(const T_arg &);
 
   func_connection(signal<T_arg> &s, function_type_1 slot) {
       _slot_1 = slot;
       _index = 1;
       s.connect(this);
   }
 
   func_connection(signal<T_arg> &s, function_type_2 slot) {
       _slot_2 = slot;
       _index = 2;
       s.connect(this);
   }
 
   void operator()(const T_arg &arg) const {
       if (_index == 1) {
           (*_slot_1)(arg);
           return;
       }
       if (_index == 2) {
           (*_slot_2)(arg);
           return;
       }
   }
 
   bool valid() const {
       return true;
   }
 
   bool operator==(base_connection<T_arg> *bc) const {
       func_connection<T_return, T_arg> *fc = dynamic_cast<func_connection<T_return, T_arg>* >(bc);
       if (fc) {
           if (_index == 1)
               return (fc->_slot_1 == _slot_1);
           if (_index == 2)
               return (fc->_slot_2 == _slot_2);
       }
       return false;
   }
 
private:
   function_type_1 _slot_1;
   function_type_2 _slot_2;
   int _index;
   func_connection();
   func_connection(const func_connection &);
};
 
template <class T_receiver, class T_return, class T_arg>
class mem_func_connection : public base_connection<T_arg>
{
public:
   typedef T_return (T_receiver::*function_type_1)(T_arg);
   typedef T_return (T_receiver::*function_type_2)(const T_arg &);
   typedef T_return (T_receiver::*function_type_3)(T_arg) const;
   typedef T_return (T_receiver::*function_type_4)(const T_arg &) const;
 
   mem_func_connection(signal<T_arg> &s, T_receiver *obj, function_type_1 slot) {
       _receiver = obj;
       _spy = _receiver->spy;
       _slot_1 = slot;
       _index = 1;
       s.connect(this);
   }
 
   mem_func_connection(signal<T_arg> &s, T_receiver *obj, function_type_2 slot) {
       _receiver = obj;
       _spy = _receiver->spy;
       _slot_2 = slot;
       _index = 2;
       s.connect(this);
   }
 
   mem_func_connection(signal<T_arg> &s, T_receiver *obj, function_type_3 slot) {
       _receiver = obj;
       _spy = _receiver->spy;
       _slot_3 = slot;
       _index = 3;
       s.connect(this);
   }
 
   mem_func_connection(signal<T_arg> &s, T_receiver *obj, function_type_4 slot) {
       _receiver = obj;
       _spy = _receiver->spy;
       _slot_4 = slot;
       _index = 4;
       s.connect(this);
   }
 
   void operator()(const T_arg &arg) const {
       if (_index == 1) {
           (_receiver->*_slot_1)(arg);
           return;
       }
       if (_index == 2) {
           (_receiver->*_slot_2)(arg);
           return;
       }
       if (_index == 3) {
           (_receiver->*_slot_3)(arg);
           return;
       }
       if (_index == 4) {
           (_receiver->*_slot_4)(arg);
           return;
       }
   }
 
   bool valid() const {
       return _spy->get();
   }
 
   bool operator==(base_connection<T_arg> *bc) const {
       mem_func_connection<T_receiver, T_return, T_arg> *mfc = dynamic_cast<mem_func_connection<T_receiver, T_return, T_arg> *>(bc);
       if (mfc && (mfc->_receiver == _receiver)) {
           if (_index == 1)
               return (mfc->_slot_1 == _slot_1);
           if (_index == 2)
               return (mfc->_slot_2 == _slot_2);
           if (_index == 3)
               return (mfc->_slot_3 == _slot_3);
           if (_index == 4)
               return (mfc->_slot_4 == _slot_4);
       }
       return false;
   }
 
private:
   T_receiver *_receiver;
   smart_ptr<trigger> _spy;
   function_type_1 _slot_1;
   function_type_2 _slot_2;
   function_type_3 _slot_3;
   function_type_4 _slot_4;
   int _index;
   mem_func_connection();
   mem_func_connection(const mem_func_connection &);
};
 
template <class T_return, class T_arg>
void connect(signal<T_arg> &s, T_return (*slot)(T_arg)) {
  new func_connection<T_return, T_arg>(s, slot);
}
 
template <class T_return, class T_arg>
void connect(signal<T_arg> &s, T_return (*slot)(const T_arg &)) {
   new func_connection<T_return, T_arg>(s, slot);
}
 
template <class T_receiver, class T_return, class T_arg>
void connect(signal<T_arg> &s, T_receiver *obj, T_return (T_receiver::*slot)(T_arg)) {
   new mem_func_connection<T_receiver, T_return, T_arg>(s, obj, slot);
}
 
template <class T_receiver, class T_return, class T_arg>
void connect(signal<T_arg> &s, T_receiver *obj, T_return (T_receiver::*slot)(const T_arg &)) {
   new mem_func_connection<T_receiver, T_return, T_arg>(s, obj, slot);
}
 
template <class T_receiver, class T_return, class T_arg>
void connect(signal<T_arg> &s, T_receiver *obj, T_return (T_receiver::*slot)(T_arg) const) {
   new mem_func_connection<T_receiver, T_return, T_arg>(s, obj, slot);
}
 
template <class T_receiver, class T_return, class T_arg>
void connect(signal<T_arg> &s, T_receiver *obj, T_return (T_receiver::*slot)(const T_arg &) const) {
   new mem_func_connection<T_receiver, T_return, T_arg>(s, obj, slot);
}
 
}
 
#endif // SIGNAL_SLOT_H
 
 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
brankovic
Гость
« Ответ #36 : Февраль 23, 2011, 21:29 »

Где подвох?

не

virtual bool operator==(base_connection<T_arg> *) const = 0;

а

virtual bool operator==(base_connection<T_arg> const &) const = 0;

мы же хотим сравнивать объект и другой объект, а не объект и указатель.
« Последнее редактирование: Февраль 23, 2011, 21:58 от brankovic » Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #37 : Февраль 23, 2011, 22:15 »

Где подвох?

не

virtual bool operator==(base_connection<T_arg> *) const = 0;

а

virtual bool operator==(base_connection<T_arg> const &) const = 0;

мы же хотим сравнивать объект и другой объект, а не объект и указатель.
Понял в чём баг..
Но в самой вункции connect  я сравниваю именно указатели
Код
C++ (Qt)
void connect(base_connection<T_arg> *c) {
       for (_iterator it = _list.begin(); it != _list.end(); it++) {
           if (c == *it) {
               delete c;
               return;
           }
       }
       _list.push_back(c);
 

Может здесь целесообразнее объявить функцию сравнения указателей?
Например:
Код
C++ (Qt)
virtual bool compare(base_connection<T_arg> *) const = 0;
 
« Последнее редактирование: Февраль 23, 2011, 22:31 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
BRE
Гость
« Ответ #38 : Февраль 23, 2011, 22:39 »

Но в самой вункции connect  я сравниваю именно указатели
А какой в этом смысл?
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #39 : Февраль 23, 2011, 23:03 »

Но в самой вункции connect  я сравниваю именно указатели
А какой в этом смысл?
В смысле?
Я должен их сравнивать, чтобы не дублировать соединения.. Если в списке уже имеется такое же соединение то и нефиг его туда вновь заносить..
Потом, мне нужно в саму функцию compare я передаю указатель и если соединение уже создано ранее, то я уничтожаю текущее.\
Или я чего то не понммаю?
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
BRE
Гость
« Ответ #40 : Февраль 23, 2011, 23:05 »

Я должен их сравнивать, чтобы не дублировать соединения.. Если в списке уже имеется такое же соединение то и нефиг его туда вновь заносить..
Потом, мне нужно в саму функцию compare я передаю указатель и если соединение уже создано ранее, то я уничтожаю текущее.\
Или я чего то не понммаю?
Если написать два одинаковых конекта, в каждом из них создастся свой объект-соединение и их указатели всегда будут разные.

И может указатели:
Код
C++ (Qt)
   function_type_1 _slot_1;
   function_type_2 _slot_2;
   function_type_3 _slot_3;
   function_type_4 _slot_4;
 
объединить в union. Для чего их все держать, если в каждый момент времени используется только один.
« Последнее редактирование: Февраль 23, 2011, 23:31 от BRE » Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #41 : Февраль 23, 2011, 23:45 »

Цитировать
Если написать два одинаковых конекта, в каждом из них создастся свой объект-соединение и их указатели всегда будут разные.
Это да, но я сейчас ввёл функцию compare:
Код
C++ (Qt)
template <class T_arg>
class base_connection
{
public:
   base_connection() {}
   virtual ~base_connection() {}
   virtual void operator() (const T_arg &) const = 0;
   virtual bool valid() const = 0;
   virtual bool compare(base_connection<T_arg> *) const = 0;
};
 
которая сравнивает не сами указатели на соединения непосредственно указатели на receiverОв и указатели на функции классов: (вот пример её реализации в классе mem_func_connection)
Код
C++ (Qt)
bool compare(base_connection<T_arg> *bc) const {
       mem_func_connection<T_receiver, T_return, T_arg> *mfc = dynamic_cast<mem_func_connection<T_receiver, T_return, T_arg> *>(bc);
       if (mfc && (mfc->_receiver == _receiver)) {
           if (_index == 1)
               return (mfc->_slot_1 == _slot_1);
           if (_index == 2)
               return (mfc->_slot_2 == _slot_2);
           if (_index == 3)
               return (mfc->_slot_3 == _slot_3);
           if (_index == 4)
               return (mfc->_slot_4 == _slot_4);
       }
       return false;
   }
 
аналогично и в случае func_conection:
Код
C++ (Qt)
bool compare(base_connection<T_arg> *bc) const {
       func_connection<T_return, T_arg> *fc = dynamic_cast<func_connection<T_return, T_arg>* >(bc);
       if (fc) {
           if (_index == 1)
               return (fc->_slot_1 == _slot_1);
           if (_index == 2)
               return (fc->_slot_2 == _slot_2);
       }
       return false;
   }
 
и теперь в самой функции connect (класс signal):
Код
C++ (Qt)
void connect(base_connection<T_arg> *c) {
       for (_iterator it = _list.begin(); it != _list.end(); it++) {
           if (c->compare(*it)) {
               delete c;
               return;
           }
       }
       _list.push_back(c);
   }
 

Такой вариант работает, я проверял))
Цитировать
И может указатели:
Код

C++ (Qt)
    function_type_1 _slot_1;
    function_type_2 _slot_2;
    function_type_3 _slot_3;
    function_type_4 _slot_4;
 

объединить в union. Для чего их все держать, если в каждый момент времени используется только один.
Хорошая идея, спасибо)
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #42 : Февраль 24, 2011, 08:41 »

Замени
Код
C++ (Qt)
...
if (_index == 1)
...
 

на
Код
C++ (Qt)
...
switch(_index) {
}
...
 

а то всё забываешь  Улыбающийся
« Последнее редактирование: Февраль 24, 2011, 08:44 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #43 : Февраль 24, 2011, 12:20 »

Сделал)
Список изменений:
1) Ввёл в базовый класс (base_connection) функцию compare замещающую функции operator==()
2) Объединил указатели на функции в union
3) Заменил все if (_index) ... на switch(_index)
4) Дополнил функционал функцией disconnect, которая возвращает true если соединение было удачно разорвано и false  в противном случае. Также теперь bool возвращают и функции connect - true в случае успешного соединения, false - в противном случае.
5) По мелочи: причесал код...

Исходники для тестирования прилагаются.
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #44 : Февраль 24, 2011, 15:26 »

И так, общими усилиями мы это сделали))
Сейчас всё работает и думаю уже приобрело законченную форму..
Ну во всяком случае можно немного успокоится)

Я тут внёс ещё одно изменение, которое не отражается на интерфейсе сигнала, но так думаю, будет более нагляднее: изменил в base_connection
Код
C++ (Qt)
virtual void operator()(const T_arg &) const = 0
 
на
Код
C++ (Qt)
virtual void handle_evant(const T_arg &) const = 0;
 

приаттачеваю на последок исходники release версии

Всем спасибо)
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Страниц: 1 2 [3] 4 5 ... 8   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.63 секунд. Запросов: 23.