//----------------------------------------------------------------------------- // 共享的模板类. // 不是 dll, 没有版本号, 因此要手工编写版本号 // V1, 2013-09-03, 5.1.1 中发布, 使用 Synchronize.hpp // V2, 2018-03-02, 7.0 中发布, 改用 std::recursive_mutex 及 std::lock_guard // V3, 2020-09-30, 7.3 中发布, 删除 XDWHolder, 改用 std::unique_ptr. 同时修改了文件名 //----------------------------------------------------------------------------- #pragma once #include #include //----------------------------------------------------------------------------- // ExclusiveHolder.tlh // 允许互斥访问一个指针对象 //----------------------------------------------------------------------------- template class ExclusiveHolder { protected: T * m_pObject; public: ExclusiveHolder (); explicit ExclusiveHolder (T * object); virtual ~ExclusiveHolder (); private: // 禁止拷贝构造函数 ExclusiveHolder (const ExclusiveHolder & h) = delete; // 禁止复制 ExclusiveHolder & operator = (const ExclusiveHolder & h) = delete; public: void Attach (T * object); T * Detach (); ExclusiveHolder & operator = (T * object); bool IsEmpty () const; void Release (); protected: mutable std::recursive_mutex m_Mutex; public: class LockHolder { public: LockHolder (const ExclusiveHolder * holder); ~LockHolder (); LockHolder (LockHolder && from); private: // 可以对同一个 ExclusiveHolder 对象反复调用 Lock, 但是 LockHolder 还是不要拷贝构造了吧 // 禁止拷贝构造函数 LockHolder (const LockHolder & h) = delete; // 禁止复制 LockHolder & operator = (const LockHolder & h) = delete; public: T * As (); const T * As () const; template C * AS (); template const C * AS () const; T * operator -> () { return As (); } const T * operator -> () const { return As (); } T & operator * () { return *As (); } const T & operator * () const { return *As (); } protected: std::unique_ptr > m_Lock; const ExclusiveHolder * m_Holder; }; public: inline LockHolder Lock () { return LockHolder (this); } inline LockHolder Lock () const { return LockHolder (this); } template void LockExec (Action action) { LockHolder holder (this); action (holder.As ()); } template void LockExec (Action action) const { LockHolder holder (this); action (holder.As ()); } };