1.关于

  • 1.1 基于原版sigslot做了部分修改。原版的信号支持最多支持8个参数,改进后,最多支持1个参数,这样肯定不能满足日常需求,但是,我们可以将信号的一个参数改为类型指针,比如信号定义时的模板传递一个结构体,这样,就可以很方便的传递多于1个的参数了,将参数做了封装放入到结构体,槽函数直接读取传过来的结构体内容。 很方便的对其做了扩展。

    简单说: 去冗余代码。
  • 1.2 改进版中增加了部分注释

    一份良好的代码需要良好的注释。可能是我水平太低,哈哈,习惯了。
  • 1.3 仅仅去除了冗余代码,并没有改变其用法,之前怎么用的,现在还是怎么用。

2.改进版

源码

//
// Written by Sarah Thompson (sarah@telergy.com) 2002.
//
// License: Public domain. You are free to use this code however you like, with the proviso that
// the author takes on no responsibility or liability for any use.
//
// QUICK DOCUMENTATION
//
// (see also the full documentation at http://sigslot.sourceforge.net/)
//
// #define switches
// SIGSLOT_PURE_ISO - Define this to force ISO C++ compliance. This also disables
// all of the thread safety support on platforms where it is
// available.
//
// SIGSLOT_USE_POSIX_THREADS - Force use of Posix threads when using a C++ compiler other than
// gcc on a platform that supports Posix threads. (When using gcc,
// this is the default - use SIGSLOT_PURE_ISO to disable this if
// necessary)
//
// SIGSLOT_DEFAULT_MT_POLICY - Where thread support is enabled, this defaults to multi_threaded_global.
// Otherwise, the default is single_threaded. #define this yourself to
// override the default. In pure ISO mode, anything other than
// single_threaded will cause a compiler error.
//
// PLATFORM NOTES
//
// Win32 - On Win32, the WIN32 symbol must be #defined. Most mainstream
// compilers do this by default, but you may need to define it
// yourself if your build environment is less standard. This causes
// the Win32 thread support to be compiled in and used automatically.
//
// Unix/Linux/BSD, etc. - If you're using gcc, it is assumed that you have Posix threads
// available, so they are used automatically. You can override this
// (as under Windows) with the SIGSLOT_PURE_ISO switch. If you're using
// something other than gcc but still want to use Posix threads, you
// need to #define SIGSLOT_USE_POSIX_THREADS.
//
// ISO C++ - If none of the supported platforms are detected, or if
// SIGSLOT_PURE_ISO is defined, all multithreading support is turned off,
// along with any code that might cause a pure ISO C++ environment to
// complain. Before you ask, gcc -ansi -pedantic won't compile this
// library, but gcc -ansi is fine. Pedantic mode seems to throw a lot of
// errors that aren't really there. If you feel like investigating this,
// please contact the author.
//
//
// THREADING MODES
//
// single_threaded - Your program is assumed to be single threaded from the point of view
// of signal/slot usage (i.e. all objects using signals and slots are
// created and destroyed from a single thread). Behaviour if objects are
// destroyed concurrently is undefined (i.e. you'll get the occasional
// segmentation fault/memory exception).
//
// multi_threaded_global - Your program is assumed to be multi threaded. Objects using signals and
// slots can be safely created and destroyed from any thread, even when
// connections exist. In multi_threaded_global mode, this is achieved by a
// single global mutex (actually a critical section on Windows because they
// are faster). This option uses less OS resources, but results in more
// opportunities for contention, possibly resulting in more context switches
// than are strictly necessary.
//
// multi_threaded_local - Behaviour in this mode is essentially the same as multi_threaded_global,
// except that each signal, and each object that inherits has_slots, all
// have their own mutex/critical section. In practice, this means that
// mutex collisions (and hence context switches) only happen if they are
// absolutely essential. However, on some platforms, creating a lot of
// mutexes can slow down the whole OS, so use this option with care.
//
// USING THE LIBRARY
//
// See the full documentation at http://sigslot.sourceforge.net/
//
//
// Libjingle specific:
// This file has been modified such that has_slots and signalx do not have to be
// using the same threading requirements. E.g. it is possible to connect a
// has_slots<single_threaded> and signal0<multi_threaded_local> or
// has_slots<multi_threaded_local> and signal0<single_threaded>.
// If has_slots is single threaded the user must ensure that it is not trying
// to connect or disconnect to signalx concurrently or data race may occur.
// If signalx is single threaded the user must ensure that disconnect, connect
// or signal is not happening concurrently or data race may occur. #ifndef _SIGSLOT_H__
#define _SIGSLOT_H__ #include <list>
#include <set>
#include <stdlib.h> // On our copy of sigslot.h, we set single threading as default.
#define SIGSLOT_DEFAULT_MT_POLICY single_threaded // 强制设定其为ISO C++编译器,并关闭所有的操作系统提供的线程安全的支持。
#if defined(SIGSLOT_PURE_ISO) || (!defined(WIN32) && !defined(__GNUG__) && !defined(SIGSLOT_USE_POSIX_THREADS))
# define _SIGSLOT_SINGLE_THREADED
#elif defined(WIN32)
# define _SIGSLOT_HAS_WIN32_THREADS
# if !defined(WIN32_LEAN_AND_MEAN)
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h> // 当使用gcc以外的编译器,而编译器支持Posix线程时,强制使用Posix线程支持。
#elif defined(__GNUG__) || defined(SIGSLOT_USE_POSIX_THREADS)
# define _SIGSLOT_HAS_POSIX_THREADS
# include <pthread.h>
#else
# define _SIGSLOT_SINGLE_THREADED
#endif // 当启用多线程支持时,默认项为全局多线程(multi_threaded_global)。否则默认项为单线程
#ifndef SIGSLOT_DEFAULT_MT_POLICY
# ifdef _SIGSLOT_SINGLE_THREADED
# define SIGSLOT_DEFAULT_MT_POLICY single_threaded
# else
# define SIGSLOT_DEFAULT_MT_POLICY multi_threaded_local
# endif
#endif // TODO: change this namespace to talk_base?
namespace sigslot
{ class single_threaded
{
public:
single_threaded()
{
;
} virtual ~single_threaded()
{
;
} virtual void lock()
{
;
} virtual void unlock()
{
;
}
}; #ifdef _SIGSLOT_HAS_WIN32_THREADS
// The multi threading policies only get compiled in if they are enabled.
class multi_threaded_global
{
public:
multi_threaded_global()
{
static bool isinitialised = false; if (!isinitialised)
{
InitializeCriticalSection(get_critsec());
isinitialised = true;
}
} multi_threaded_global(const multi_threaded_global&)
{
;
} virtual ~multi_threaded_global()
{
;
} virtual void lock()
{
EnterCriticalSection(get_critsec());
} virtual void unlock()
{
LeaveCriticalSection(get_critsec());
} private:
CRITICAL_SECTION* get_critsec()
{
static CRITICAL_SECTION g_critsec;
return &g_critsec;
}
}; class multi_threaded_local
{
public:
multi_threaded_local()
{
InitializeCriticalSection(&m_critsec);
} multi_threaded_local(const multi_threaded_local&)
{
InitializeCriticalSection(&m_critsec);
} virtual ~multi_threaded_local()
{
DeleteCriticalSection(&m_critsec);
} virtual void lock()
{
EnterCriticalSection(&m_critsec);
} virtual void unlock()
{
LeaveCriticalSection(&m_critsec);
} private:
CRITICAL_SECTION m_critsec;
};
#endif // _SIGSLOT_HAS_WIN32_THREADS #ifdef _SIGSLOT_HAS_POSIX_THREADS
// The multi threading policies only get compiled in if they are enabled.
class multi_threaded_global
{
public:
multi_threaded_global()
{
pthread_mutex_init(get_mutex(), NULL);
} multi_threaded_global(const multi_threaded_global&)
{
;
} virtual ~multi_threaded_global()
{
;
} virtual void lock()
{
pthread_mutex_lock(get_mutex());
} virtual void unlock()
{
pthread_mutex_unlock(get_mutex());
} private:
pthread_mutex_t* get_mutex()
{
static pthread_mutex_t g_mutex;
return &g_mutex;
}
}; class multi_threaded_local
{
public:
multi_threaded_local()
{
pthread_mutex_init(&m_mutex, NULL);
} multi_threaded_local(const multi_threaded_local&)
{
pthread_mutex_init(&m_mutex, NULL);
} virtual ~multi_threaded_local()
{
pthread_mutex_destroy(&m_mutex);
} virtual void lock()
{
pthread_mutex_lock(&m_mutex);
} virtual void unlock()
{
pthread_mutex_unlock(&m_mutex);
} private:
pthread_mutex_t m_mutex;
};
#endif // _SIGSLOT_HAS_POSIX_THREADS /**
* @brief: 锁对象:
lock_block模板类,最终根据实例化的模板类使用相应的线程模型和同步对象,
只需要将该类实例化到需要的位置即实现了线程同步功能,这是比较规范并简单有效的方法。
mt_policy被指定为SIGSLOT_DEFAULT_MT_POLICY宏,同时也作为一个强制指定为单线程模型的开关。
*/
template<class mt_policy>
class lock_block
{
public:
mt_policy *m_mutex; lock_block(mt_policy *mtx)
: m_mutex(mtx)
{
m_mutex->lock();
} ~lock_block()
{
m_mutex->unlock();
}
}; //---------------------------------------------------------------------------------------- class has_slots_interface;
/**
* @brief: 连接对象接口类
*/
template<class mt_policy>
class _connection_base0
{
public:
virtual ~_connection_base0() {}
virtual has_slots_interface* getdest() const = 0;
virtual void emit() = 0;
virtual _connection_base0* clone() = 0;
virtual _connection_base0* duplicate(has_slots_interface* pnewdest) = 0;
}; /**
* @brief: 连接对象 _connection0 ... _connection8
_connection0<dest_type,mt_policy>...
_connection8<dest_type,arg1_type...arg8_type,mt_policy>
是接口:
_connection_base0<mt_policy> ...
_connection_base8<arg1_type,...arg8_type,mt_policy>的实现类,其中: clone():
使用默认拷贝构造函数返回一个新的_connection_baseN对象指针。 duplicate(sigslot::has_slots<mt_policy> *pnewdest):
返回一个新的目标对象为pnewdest的_connection_baseN对象指针。 emit(arg0_type a0..argN_type aN):
触发_connection_baseN中目标对象中指定的函数指针。 getdest(void)const:
返回目标对象指针。
*/
template<class arg1_type, class mt_policy>
class _connection_base1
{
public:
virtual ~_connection_base1() {}
virtual has_slots_interface* getdest() const = 0;
virtual void emit(arg1_type) = 0;
virtual _connection_base1<arg1_type, mt_policy>* clone() = 0;
virtual _connection_base1<arg1_type, mt_policy>* duplicate(has_slots_interface* pnewdest) = 0;
}; //-------------------------------------------------------------------------------------------------------------- /**
* @brief: 信号接口
*/
class _signal_base_interface
{
public:
virtual void slot_disconnect(has_slots_interface* pslot) = 0;
virtual void slot_duplicate(const has_slots_interface* poldslot, has_slots_interface* pnewslot) = 0;
}; /**
* @brief: 扩展信号接口类
*/
template<class mt_policy>
class _signal_base : public _signal_base_interface, public mt_policy
{
}; /**
* @brief:信号槽接口类,
*/
class has_slots_interface
{
public:
has_slots_interface()
{
;
} virtual void signal_connect(_signal_base_interface* sender) = 0; virtual void signal_disconnect(_signal_base_interface* sender) = 0; virtual ~has_slots_interface()
{
} virtual void disconnect_all() = 0;
}; /**
* @brief: 扩展信号槽接口
*/
template<class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
class has_slots : public has_slots_interface, public mt_policy
{
private:
typedef std::set<_signal_base_interface*> sender_set;
typedef sender_set::const_iterator const_iterator; public:
has_slots()
{
;
} has_slots(const has_slots& hs)
{
lock_block<mt_policy> lock(this);
const_iterator it = hs.m_senders.begin();
const_iterator itEnd = hs.m_senders.end(); while (it != itEnd)
{
(*it)->slot_duplicate(&hs, this);
m_senders.insert(*it);
++it;
}
} void signal_connect(_signal_base_interface* sender)
{
lock_block<mt_policy> lock(this);
m_senders.insert(sender);
} void signal_disconnect(_signal_base_interface* sender)
{
lock_block<mt_policy> lock(this);
m_senders.erase(sender);
} virtual ~has_slots()
{
disconnect_all();
} void disconnect_all()
{
lock_block<mt_policy> lock(this);
const_iterator it = m_senders.begin();
const_iterator itEnd = m_senders.end(); while (it != itEnd)
{
(*it)->slot_disconnect(this);
++it;
} m_senders.erase(m_senders.begin(), m_senders.end());
} private:
sender_set m_senders;
}; /**
* @brief: 信号对象
*/
template<class mt_policy>
class _signal_base0 : public _signal_base<mt_policy>
{
public:
typedef std::list<_connection_base0<mt_policy> *> connections_list; _signal_base0()
{
;
} _signal_base0(const _signal_base0& s)
: _signal_base<mt_policy>(s)
{
lock_block<mt_policy> lock(this);
typename connections_list::const_iterator it = s.m_connected_slots.begin();
typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); while (it != itEnd)
{
(*it)->getdest()->signal_connect(this);
m_connected_slots.push_back((*it)->clone()); ++it;
}
} ~_signal_base0()
{
disconnect_all();
} bool is_empty()
{
lock_block<mt_policy> lock(this);
typename connections_list::const_iterator it = m_connected_slots.begin();
typename connections_list::const_iterator itEnd = m_connected_slots.end();
return it == itEnd;
} void disconnect_all()
{
lock_block<mt_policy> lock(this);
typename connections_list::const_iterator it = m_connected_slots.begin();
typename connections_list::const_iterator itEnd = m_connected_slots.end(); while (it != itEnd)
{
(*it)->getdest()->signal_disconnect(this);
delete *it; ++it;
} m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
} #ifdef _DEBUG
bool connected(has_slots_interface* pclass)
{
lock_block<mt_policy> lock(this);
typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
typename connections_list::const_iterator itEnd = m_connected_slots.end();
while (it != itEnd)
{
itNext = it;
++itNext;
if ((*it)->getdest() == pclass)
return true;
it = itNext;
}
return false;
}
#endif void disconnect(has_slots_interface* pclass)
{
lock_block<mt_policy> lock(this);
typename connections_list::iterator it = m_connected_slots.begin();
typename connections_list::iterator itEnd = m_connected_slots.end(); while (it != itEnd)
{
if ((*it)->getdest() == pclass)
{
delete *it;
m_connected_slots.erase(it);
pclass->signal_disconnect(this);
return;
} ++it;
}
} void slot_disconnect(has_slots_interface* pslot)
{
lock_block<mt_policy> lock(this);
typename connections_list::iterator it = m_connected_slots.begin();
typename connections_list::iterator itEnd = m_connected_slots.end(); while (it != itEnd)
{
typename connections_list::iterator itNext = it;
++itNext; if ((*it)->getdest() == pslot)
{
delete *it;
m_connected_slots.erase(it);
} it = itNext;
}
} void slot_duplicate(const has_slots_interface* oldtarget, has_slots_interface* newtarget)
{
lock_block<mt_policy> lock(this);
typename connections_list::iterator it = m_connected_slots.begin();
typename connections_list::iterator itEnd = m_connected_slots.end(); while (it != itEnd)
{
if ((*it)->getdest() == oldtarget)
{
m_connected_slots.push_back((*it)->duplicate(newtarget));
} ++it;
}
} protected:
connections_list m_connected_slots;
}; /**
* @brief: 信号对象 Signal0 ... Signal8 以带一个参数的信号对象为例:signal1<arg1_type,mt_policy>的emit(arg1_type a1)
与 重载运算符operator ()(arg1_type a1)功能是一致的。
都是遍历父类成员m_connected_slots中的_connection_base1<arg1_type,
mt_policy>指针元素,逐一的调用_connection_base1中的emit(a1)函数最终使目标函数被调用。 函数connect()生成模板参数的目标对象和目标函数指针,并将该新连接加入到已连接的列表m_connected_slots中。
最后使用has_slots的signal_connect函数,将signal1信号对象加入到has_slots的m_senders列表中
*/
template<class arg1_type, class mt_policy>
class _signal_base1 : public _signal_base<mt_policy>
{
public:
typedef std::list<_connection_base1<arg1_type, mt_policy> *> connections_list; _signal_base1()
{
;
} _signal_base1(const _signal_base1<arg1_type, mt_policy>& s)
: _signal_base<mt_policy>(s)
{
lock_block<mt_policy> lock(this);
typename connections_list::const_iterator it = s.m_connected_slots.begin();
typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); while (it != itEnd)
{
(*it)->getdest()->signal_connect(this);
m_connected_slots.push_back((*it)->clone()); ++it;
}
} void slot_duplicate(const has_slots_interface* oldtarget, has_slots_interface* newtarget)
{
lock_block<mt_policy> lock(this);
typename connections_list::iterator it = m_connected_slots.begin();
typename connections_list::iterator itEnd = m_connected_slots.end(); while (it != itEnd)
{
if ((*it)->getdest() == oldtarget)
{
m_connected_slots.push_back((*it)->duplicate(newtarget));
} ++it;
}
} ~_signal_base1()
{
disconnect_all();
} bool is_empty()
{
lock_block<mt_policy> lock(this);
typename connections_list::const_iterator it = m_connected_slots.begin();
typename connections_list::const_iterator itEnd = m_connected_slots.end();
return it == itEnd;
} void disconnect_all()
{
lock_block<mt_policy> lock(this);
typename connections_list::const_iterator it = m_connected_slots.begin();
typename connections_list::const_iterator itEnd = m_connected_slots.end(); while (it != itEnd)
{
(*it)->getdest()->signal_disconnect(this);
delete *it; ++it;
} m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
} #ifdef _DEBUG
bool connected(has_slots_interface* pclass)
{
lock_block<mt_policy> lock(this);
typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
typename connections_list::const_iterator itEnd = m_connected_slots.end();
while (it != itEnd)
{
itNext = it;
++itNext;
if ((*it)->getdest() == pclass)
return true;
it = itNext;
}
return false;
}
#endif void disconnect(has_slots_interface* pclass)
{
lock_block<mt_policy> lock(this);
typename connections_list::iterator it = m_connected_slots.begin();
typename connections_list::iterator itEnd = m_connected_slots.end(); while (it != itEnd)
{
if ((*it)->getdest() == pclass)
{
delete *it;
m_connected_slots.erase(it);
pclass->signal_disconnect(this);
return;
} ++it;
}
} void slot_disconnect(has_slots_interface* pslot)
{
lock_block<mt_policy> lock(this);
typename connections_list::iterator it = m_connected_slots.begin();
typename connections_list::iterator itEnd = m_connected_slots.end(); while (it != itEnd)
{
typename connections_list::iterator itNext = it;
++itNext; if ((*it)->getdest() == pslot)
{
delete *it;
m_connected_slots.erase(it);
} it = itNext;
}
} protected:
connections_list m_connected_slots;
}; /**
* @brief: _connection0 ... _connection8
_connection0<dest_type,mt_policy>...
_connection8<dest_type,arg1_type...arg8_type,mt_policy>
是接口:
_connection_base0<mt_policy> ...
_connection_base8<arg1_type,...arg8_type,mt_policy>的实现类,其中: clone():
使用默认拷贝构造函数返回一个新的_connection_baseN对象指针。 duplicate(sigslot::has_slots<mt_policy> *pnewdest):
返回一个新的目标对象为pnewdest的_connection_baseN对象指针。 emit(arg0_type a0..argN_type aN):
触发_connection_baseN中目标对象中指定的函数指针。 getdest(void)const:
返回目标对象指针。
*/
template<class dest_type, class mt_policy>
class _connection0 : public _connection_base0<mt_policy>
{
public:
_connection0()
{
m_pobject = NULL;
m_pmemfun = NULL;
} _connection0(dest_type* pobject, void (dest_type::*pmemfun)())
{
m_pobject = pobject;
m_pmemfun = pmemfun;
} virtual ~_connection0()
{
} virtual _connection_base0<mt_policy>* clone()
{
return new _connection0<dest_type, mt_policy>(*this);
} virtual _connection_base0<mt_policy>* duplicate(has_slots_interface* pnewdest)
{
return new _connection0<dest_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);
} virtual void emit()
{
(m_pobject->*m_pmemfun)();
} virtual has_slots_interface* getdest() const
{
return m_pobject;
} private:
dest_type* m_pobject;
void (dest_type::* m_pmemfun)();
}; /**
* @brief: _connection0 ... _connection8
_connection0<dest_type,mt_policy>...
_connection8<dest_type,arg1_type...arg8_type,mt_policy>
是接口:
_connection_base0<mt_policy> ...
_connection_base8<arg1_type,...arg8_type,mt_policy>的实现类,其中: clone():
使用默认拷贝构造函数返回一个新的_connection_baseN对象指针。 duplicate(sigslot::has_slots<mt_policy> *pnewdest):
返回一个新的目标对象为pnewdest的_connection_baseN对象指针。 emit(arg0_type a0..argN_type aN):
触发_connection_baseN中目标对象中指定的函数指针。 getdest(void)const:
返回目标对象指针。
*/
template<class dest_type, class arg1_type, class mt_policy>
class _connection1 : public _connection_base1<arg1_type, mt_policy>
{
public:
_connection1()
{
m_pobject = NULL;
m_pmemfun = NULL;
} _connection1(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type))
{
m_pobject = pobject;
m_pmemfun = pmemfun;
} virtual ~_connection1()
{
} virtual _connection_base1<arg1_type, mt_policy>* clone()
{
return new _connection1<dest_type, arg1_type, mt_policy>(*this);
} virtual _connection_base1<arg1_type, mt_policy>* duplicate(has_slots_interface* pnewdest)
{
return new _connection1<dest_type, arg1_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);
} virtual void emit(arg1_type a1)
{
(m_pobject->*m_pmemfun)(a1);
} virtual has_slots_interface* getdest() const
{
return m_pobject;
} private:
dest_type* m_pobject;
void (dest_type::* m_pmemfun)(arg1_type);
}; /**
* @brief: 信号对象
以带一个参数的信号对象为例:signal1<arg1_type,mt_policy>的emit(arg1_type a1)
与 重载运算符operator ()(arg1_type a1)功能是一致的。
都是遍历父类成员m_connected_slots中的_connection_base1<arg1_type, mt_policy>指针元素,
逐一的调用_connection_base1中的emit(a1)函数最终使目标函数被调用。 函数connect()生成模板参数的目标对象和目标函数指针,
并将该新连接加入到已连接的列表m_connected_slots中。
最后使用has_slots的signal_connect函数,将signal1信号对象加入到has_slots的m_senders列表中。
*/
template<class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
class signal0 : public _signal_base0<mt_policy>
{
public:
typedef _signal_base0<mt_policy> base;
typedef typename base::connections_list connections_list;
using base::m_connected_slots; signal0()
{
;
} signal0(const signal0<mt_policy>& s)
: _signal_base0<mt_policy>(s)
{
;
} template<class desttype>
void connect(desttype* pclass, void (desttype::*pmemfun)())
{
lock_block<mt_policy> lock(this);
_connection0<desttype, mt_policy>* conn =
new _connection0<desttype, mt_policy>(pclass, pmemfun);
m_connected_slots.push_back(conn);
pclass->signal_connect(this);
} void emit()
{
lock_block<mt_policy> lock(this);
typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
typename connections_list::const_iterator itEnd = m_connected_slots.end(); while (it != itEnd)
{
itNext = it;
++itNext; (*it)->emit(); it = itNext;
}
} void operator()()
{
lock_block<mt_policy> lock(this);
typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
typename connections_list::const_iterator itEnd = m_connected_slots.end(); while (it != itEnd)
{
itNext = it;
++itNext; (*it)->emit(); it = itNext;
}
}
}; /**
* @brief: 信号对象
以带一个参数的信号对象为例:signal1<arg1_type,mt_policy>的emit(arg1_type a1)
与 重载运算符operator ()(arg1_type a1)功能是一致的。
都是遍历父类成员m_connected_slots中的_connection_base1<arg1_type, mt_policy>指针元素,
逐一的调用_connection_base1中的emit(a1)函数最终使目标函数被调用。 函数connect()生成模板参数的目标对象和目标函数指针,
并将该新连接加入到已连接的列表m_connected_slots中。
最后使用has_slots的signal_connect函数,将signal1信号对象加入到has_slots的m_senders列表中。
*/
template<class arg1_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
class signal1 : public _signal_base1<arg1_type, mt_policy>
{
public:
typedef _signal_base1<arg1_type, mt_policy> base;
typedef typename base::connections_list connections_list;
using base::m_connected_slots; signal1()
{
;
} signal1(const signal1<arg1_type, mt_policy>& s)
: _signal_base1<arg1_type, mt_policy>(s)
{
;
} template<class desttype>
void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type))
{
lock_block<mt_policy> lock(this);
_connection1<desttype, arg1_type, mt_policy>* conn =
new _connection1<desttype, arg1_type, mt_policy>(pclass, pmemfun);
m_connected_slots.push_back(conn);
pclass->signal_connect(this);
} void emit(arg1_type a1)
{
lock_block<mt_policy> lock(this);
typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
typename connections_list::const_iterator itEnd = m_connected_slots.end(); while (it != itEnd)
{
itNext = it;
++itNext; (*it)->emit(a1); it = itNext;
}
} void operator()(arg1_type a1)
{
lock_block<mt_policy> lock(this);
typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
typename connections_list::const_iterator itEnd = m_connected_slots.end(); while (it != itEnd)
{
itNext = it;
++itNext; (*it)->emit(a1); it = itNext;
}
} }; // end class }; // namespace sigslot #endif // _SIGSLOT_H__s

sigslot之简化版的更多相关文章

  1. C++消息框架-基于sigslot

    目录 一.简介 二.消息 三.发送者 1.发送消息函数 2.新增一个接收者函数 3.移除一个接收者函数 四.接收者 五.功能测试 1.消息接收类 2.测试代码 3.测试结果 六.源码 一.简介 上一篇 ...

  2. 机器学习——支持向量机(SVM)之拉格朗日乘子法,KKT条件以及简化版SMO算法分析

    SVM有很多实现,现在只关注其中最流行的一种实现,即序列最小优化(Sequential Minimal Optimization,SMO)算法,然后介绍如何使用一种核函数(kernel)的方式将SVM ...

  3. coreDate 简化版

    建表: 自动生成: 代码: // // RootViewController.m // coreDate 简化版 #import "RootViewController.h" #i ...

  4. 学习OpenCV——ORB简化版&Location加速版

    根据前面surf简化版的结构,重新把ORB检测的代码给简化以下,发现虽然速度一样,确实能省好多行代码,关键是有 BruteForceMatcher<HammingLUT>matcher的帮 ...

  5. [vijos P1014] 旅行商简化版

    昨天早上上课讲旅行商问题,有点难,这周抽空把3^n的算法码码看.不过这个简化版已经够折腾人了. 其一不看解析不知道这是双进程动态规划,不过我看的解析停留在f[i,j]表示第一个人走到i.第二个人走到j ...

  6. 简化版的Flappy Bird开发过程(不使用第三方框架)

    目录 .1构造世界 .2在世界中添加元素 .3碰撞检测 .4添加动画特效 .5总结 .0 开始之前 之前曾经用Html5/JavaScript/CSS实现过2048,用Cocos2d-html5/Ch ...

  7. vijosP1014 旅行商简化版

    vijosP1014 旅行商简化版 链接:https://vijos.org/p/1014 [思路] 双线DP. 设ab,ab同时走.用d[i][j]表示ab所处结点i.j,且定义i>j,则有转 ...

  8. redux-simple 简化版的redux

    作为react的粉丝,当然要吐槽一下react组件通信问题.react的单向数据流是组件通信的一大阻碍,只允许父组件向子组件传值,子组件向父组件传值只能通过父组件向子组件传递回调函数实现.如果在深层次 ...

  9. 信号和槽有一个非常精炼的C++实现,作者是Sarah Thompson,该实现只有一个头文件sigslot.h,跨平台且线程安全

    关于信号和槽有一个非常精炼的C++实现,作者是Sarah Thompson,该实现只有一个头文件sigslot.h,跨平台且线程安全. 源码在:http://sigslot.cvs.sourcefor ...

随机推荐

  1. 数据仓库分层中的ODS、DWD、DWS

    1.数据仓库DW 1.1简介 Data warehouse(可简写为DW或者DWH)数据仓库,是在数据库已经大量存在的情况下,为了进一步挖掘数据资源.为了决策需要而产生的,它是一整套包括了etl.调度 ...

  2. Python基础笔记4

    模块 模块是一组Python代码的集合,一个.py文件就称之为一个模块(Module),按目录来组织模块称为包(Package).优点:提高了代码的可维护性:避免函数名和变量名冲突. mycompan ...

  3. R语言与医学统计图形-【23】ggplot2坐标系转换函数

    ggplot2绘图系统--坐标系转换函数 包括饼图.环状条图.玫瑰图.戒指图.坐标翻转. 笛卡尔坐标系(最常见). ArcGIS地理坐标系(地图). Cartesian坐标系. polar极坐标系. ...

  4. Linux搭建yum仓库

    1.安装nginx 2.为nginx搭建共享目录 3.安装createrepo,创建存储库 4.客户端测试 1.安装nginx yum list |grep nginx #查看是否有可用的nginx包 ...

  5. springcloud - alibaba - 2 - 集成Feign - 更新完成

    1.依赖 依赖管理 <parent> <artifactId>spring-boot-parent</artifactId> <groupId>org. ...

  6. A Child's History of England.29

    You have not forgotten the New Forest which the Conqueror made, and which the miserable people whose ...

  7. Spark(八)【利用广播小表实现join避免Shuffle】

    目录 使用场景 核心思路 代码演示 正常join 正常left join 广播:join 广播:left join 不适用场景 使用场景 大表join小表 只能广播小表 普通的join是会走shuff ...

  8. CR LF 的含义

    可以参考: 转载于:https://www.cnblogs.com/babykick/archive/2011/03/25/1995977.html

  9. 'this' pointer in C++

    The 'this' pointer is passed as a hidden argument to all nonstatic member function calls and is avai ...

  10. 【Linux】【Services】【Docker】网络

    容器的网络模型: closed container: 仅有一个接口:loopback 不参与网络通信,仅适用于无须网络通信的应用场景,例如备份.程序调试等: --net none bridged co ...