C++ (Qt)#include <iostream>#include <string>#include "signal_slot.h" class A{public: A() { std::cout << "A()" << std::endl; } ~A() { std::cout << "~A()" << std::endl; } ssc::signal<void, std::string> my_signal; void run() { my_signal("Hello Word!"); }}; class B{public: B() : _i(0) { std::cout << "B()" << std::endl; } B(int i) : _i(i) { std::cout << "B(int i = " << _i << ")" << std::endl; } ~B() { std::cout << "~B(); i = " << _i << std::endl; } void slot1(const std::string &str) { std::cout << "slot1, signal - " << str << " i = " << _i << std::endl; } void slot2(std::string str) const { std::cout << "slot2, signal - " << str << " i = " << _i << std::endl; }private: int _i;}; int main(){ ssc::smart_ptr<A> a = new A; // A *a = new A; можно и так, но придётся удалять руками //{ если раскомментировать, соединения автоматически разорвуться ssc::smart_ptr<B> p(new B(12)); /* B *b = new B(12) а вот так можно, но в connect мы его не сможем засунуть поскольку connect хочет чтоб b был умным)) */ connect(a->my_signal, p, &B::slot1); connect(a->my_signal, p, &B::slot2); //} см. выше a->run(); return 0;}
C++ (Qt)smart_ptr<B> p1(new B); // p1 - киллер и убъёт объектsmart_ptr<B> p2 = p1; /* p2 - не имееет права убивать объект, он просто копирует указатель на на него. флаг _is_killer = false. Сам объект не клонируется. */
C++ (Qt)smart_ptr<B> p1(new B); // p1 - киллер и убъёт объектsmart_ptr<B> p2(new B); // p2 - тоже киллер!// Внимание фокус!p2 = p1; /* Поскольку p2 - киллер он вначале убъёт объект на который ссылается, затем скопирует указатель на объект на который ссылается p1. Далее он сбросит флаг _is_killer = false и лишится права удалять объект, поскольку им уже владел до него p1 и владеет. Флаг _valid он скопирует также, и соответственно _valid == true, так что пока всё хорошо)) */// А вот здесь: p1 = p2; /* Ничего не произойдёт, поскольку operatop=() сначало проверяет не ссылаютсяли они на один и тот же объект. И если да (а в данном случае так и есть)то return *this и всё.*/
smart_ptr<B> p1(new B); // p1 - киллер и убъёт объектsmart_ptr<B> p2(new B); // p2 - тоже киллер!// Внимание фокус!p2 = p1; /* Поскольку p2 - киллер он вначале убъёт объект на который ссылается,
C++ (Qt)class B{public: B() {} void slot1(const std::string &str) { std::cout << "slot1, signal - " << str << std::endl; } void slot2(std::string str) const { std::cout << "slot2, signal - " << str << std::endl; } ssc::spy spy; // Вот этот объект. Его предназначение, следить за своим владельцем. private: int _i;};
C++ (Qt)int main(){ A *a = new A; B *b = new B(12); connect(a->my_signal, b, &B::slot1, b->spy); connect(a->my_signal, b, &B::slot2, b->spy); a->run(); return 0;}
C++ (Qt)class spy{public: spy() : _valid(new bool(true)) {} ~spy() { *_valid = false; } bool operator()() const { return *_valid; } template <class T1, class T2, class T3> friend class manager_connection;private: bool *_valid;};
C++ (Qt)class CMyClass : public CSignalReceiver, public CSignalSender {..
C++ (Qt)#ifndef SMART_PTR_H#define SMART_PTR_H namespace ssc { template <class T>class smart_ptr{public: smart_ptr(); smart_ptr(const smart_ptr<T> &other); smart_ptr(T *p); ~smart_ptr(); bool is_null() const; T* operator->() const; T& operator*() const; T* get() const; smart_ptr<T> &operator=(const smart_ptr<T> &p); private: T *_obj; int *_counter; void try_destroy(); smart_ptr<T> &operator=(T*);}; template <class T>inline smart_ptr<T>::smart_ptr() : _obj(0), _counter(0){} template <class T>inline smart_ptr<T>::smart_ptr(const smart_ptr<T> &other) : _obj(other._obj), _counter(other._counter){ if (_counter) (*_counter)++;} template <class T>inline smart_ptr<T>::smart_ptr(T *p) : _obj(p), _counter(new int(1)){} template <class T>inline void smart_ptr<T>::try_destroy(){ if (!_obj) return; if ((*_counter) == 1) { delete _counter; _counter = 0; delete _obj; _obj = 0; }} template <class T>inline smart_ptr<T>::~smart_ptr(){ try_destroy();} template <class T>inline bool smart_ptr<T>::is_null() const{ return !_obj;} template <class T>inline T* smart_ptr<T>::operator->() const{ return _obj;} template <class T>inline T& smart_ptr<T>::operator*() const{ return *_obj;} template <class T>inline T* smart_ptr<T>::get() const{ return _obj;} template <class T>inline smart_ptr<T>& smart_ptr<T>::operator=(const smart_ptr<T> &p){ if (_obj != p._obj) { try_destroy(); _counter = p._counter; _obj = p._obj; if (_counter) (*_counter)++; } return *this;} template <class T>inline smart_ptr<T>& smart_ptr<T>::operator=(T*){ return *this;} template <class T>inline bool operator==(const T *o, const smart_ptr<T> &p){ return o == p.operator->();} template<class T>inline bool operator==(const smart_ptr<T> &p, const T *o){ return p.operator->() == o;} template <class T>inline bool operator==(T *o, const smart_ptr<T> &p){ return o == p.operator->();} template<class T>inline bool operator==(const smart_ptr<T> &p, T *o){ return p.operator->() == o;} template<class T>inline bool operator==(const smart_ptr<T> &p1, const smart_ptr<T> &p2){ return p1.operator->() == p2.operator->();} template <class T>inline bool operator!=(const T *o, const smart_ptr<T> &p){ return o != p.operator->();} template<class T>inline bool operator!= (const smart_ptr<T> &p, const T *o){ return p.operator->() != o;} template <class T>inline bool operator!=(T *o, const smart_ptr<T> &p){ return o != p.operator->();} template<class T>inline bool operator!= (const smart_ptr<T> &p, T *o){ return p.operator->() != o;} template<class T>inline bool operator!= (const smart_ptr<T> &p1, const smart_ptr<T> &p2){ return p1.operator->() != p2.operator->();} } #endif // SMART_PTR_H
C++ (Qt)#include <iostream>#include <string>#include "signal_slot.h" /* Класс A испускает сигналы */class A{public: A() {} ssc::signal<void, std::string> my_signal; void run() { my_signal("Hello Word!"); }}; /* Класс B содержит слоты, поэтому он должен отнаследоваться от trackable */class B : public ssc::trackable{public: B() {} void slot1(const std::string &str) { std::cout << "slot1, signal - " << str << std::endl; } void slot2(std::string str) const { std::cout << "slot2, signal - " << str << std::endl; }}; 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;}
C++ (Qt)template <class T_return, class T_arg> class base_signal
C++ (Qt)virtual T_return operator() (const T_arg &) const = 0;virtual bool valid() const = 0;
C++ (Qt)template <class T_return, class T_arg> class signal
C++ (Qt)T_return operator() (const T_arg &arg) const
C++ (Qt)template <class T_receiver, class T_return, class T_arg>class manager_connection : public base_signal<T_return, T_arg>
C++ (Qt)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;};
C++ (Qt)private: T_receiver *_receiver; // указатель на receiver smart_ptr<trigger> _spy; // шпион, он же trackable ...
C++ (Qt)manager_connection(signal<T_return, T_arg> &s, T_receiver *obj, function_type_4 slot) { _receiver = obj; // копируем указатель _spy = _receiver->spy; /* копируем шпиона, который вкурсе что происходит с receiverОМ по средством функции bool get() const */ _slot_4 = slot; _index = 4; s.connect(this); // Заносим данное соединение в список соединений нашего сигнала }
C++ (Qt)template <class T_receiver, class T_return, class T_arg>void connect(signal<T_return, T_arg> &s, T_receiver *obj, T_return (T_receiver::*slot)(T_arg)) { new manager_connection<T_receiver, T_return, T_arg>(s, obj, slot);}