You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
184 lines
6.2 KiB
184 lines
6.2 KiB
9 years ago
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
/**
|
||
|
* \file static_singleton.hpp
|
||
|
* \date 6.8.2009
|
||
|
* \author Potěšil Josef xpotes03
|
||
|
* \brief Soubor obsahuje šablonu třídy cStaticSingleton.
|
||
|
*/
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
|
||
|
#ifndef _STATIC_SINGLETON_HPP_
|
||
|
#define _STATIC_SINGLETON_HPP_
|
||
|
|
||
|
#include <stdexcept>
|
||
|
#include <boost/noncopyable.hpp>
|
||
|
#include <boost/thread/mutex.hpp>
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
/**
|
||
|
* \brief Předdefinovaná třída podporující model větvení do vláken pro
|
||
|
* spolupráci s šablonou cStaticSingleton pro použití ve vícevláknových
|
||
|
* aplikacích. Využívá zámky z knihovny Boost::Threads.
|
||
|
*/
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
struct MultiThreading
|
||
|
{
|
||
|
typedef boost::mutex mutex;
|
||
|
typedef boost::mutex::scoped_lock scoped_lock;
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
/**
|
||
|
* \brief Předdefinovaná třída pro spolupráci s šablonou cStaticSingleton pro
|
||
|
* použití v jednovláknových aplikacích.
|
||
|
*/
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
class SingleThreading
|
||
|
{
|
||
|
struct empty {};
|
||
|
struct scoped_guard
|
||
|
{
|
||
|
scoped_guard(empty& ) {}
|
||
|
};
|
||
|
public:
|
||
|
typedef empty mutex;
|
||
|
typedef scoped_guard scoped_lock;
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
/**
|
||
|
* \brief Šablonová třída obsahující jednoduchou implementaci návrhového vzoru
|
||
|
* Singleton, která umožňuje vytvořit jedináčka z jakékoli třídy, která
|
||
|
* má bezparametrový konstruktor.
|
||
|
*/
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
template<class Host, class ThreadingModel = SingleThreading>
|
||
|
class cStaticSingleton
|
||
|
{
|
||
|
public:
|
||
|
static Host* Instance();
|
||
|
static Host& GetInstance();
|
||
|
|
||
|
private:
|
||
|
cStaticSingleton();
|
||
|
cStaticSingleton(const cStaticSingleton& s);
|
||
|
cStaticSingleton& operator=(const cStaticSingleton& s);
|
||
|
~cStaticSingleton();
|
||
|
static Host& Create();
|
||
|
static Host& Access();
|
||
|
|
||
|
typedef Host& (*access_function)();
|
||
|
|
||
|
static Host* _instance;
|
||
|
static bool _destroyed;
|
||
|
static access_function _access;
|
||
|
static typename ThreadingModel::mutex _mutex;
|
||
|
};
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
/**
|
||
|
* \brief Funkce pro přístup k jediné instanci třídy.
|
||
|
* \return Ukazatele na instanci.
|
||
|
*/
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
template<class Host, class ThreadingModel>
|
||
|
inline Host* cStaticSingleton<Host, ThreadingModel>::Instance()
|
||
|
{
|
||
|
return &(GetInstance());
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
/**
|
||
|
* \brief Funkce pro přístup k jediné instanci třídy.
|
||
|
* \return Referenci instanci.
|
||
|
*/
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
template<class Host, class ThreadingModel>
|
||
|
inline Host& cStaticSingleton<Host, ThreadingModel>::GetInstance()
|
||
|
{
|
||
|
return _access();
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
/**
|
||
|
* \brief Konstruktor.
|
||
|
*/
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
template<class Host, class ThreadingModel>
|
||
|
cStaticSingleton<Host, ThreadingModel>::cStaticSingleton()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
/**
|
||
|
* \brief Destruktor.
|
||
|
*/
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
template<class Host, class ThreadingModel>
|
||
|
cStaticSingleton<Host, ThreadingModel>::~cStaticSingleton()
|
||
|
{
|
||
|
_instance = 0;
|
||
|
_destroyed = true;
|
||
|
_access = &cStaticSingleton<Host, ThreadingModel>::Create;
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
/**
|
||
|
* \brief Interní funkce třídy vytvářející samotnou instanci objektu.
|
||
|
* Pro korektní práci ve vícevláknovém prostředí je potřeba
|
||
|
* odkomentovat/upravit testující a uzamykací část
|
||
|
*/
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
template<class Host, class ThreadingModel>
|
||
|
Host& cStaticSingleton<Host, ThreadingModel>::Create()
|
||
|
{
|
||
|
typename ThreadingModel::scoped_lock scoped_lock(_mutex);
|
||
|
if (!_instance)
|
||
|
{
|
||
|
if (!_destroyed)
|
||
|
{ // Vytvoř jedinou instanci a změň ukazatele _access, kterým byla
|
||
|
// tato metoda zavolána, aby se již nezavolala a místo toho
|
||
|
// se volala funkce zpřístupňující samotnou instanci
|
||
|
static Host staticInstance;
|
||
|
_instance = &staticInstance;
|
||
|
_access = &cStaticSingleton<Host, ThreadingModel>::Access;
|
||
|
}
|
||
|
else
|
||
|
{ // Došlo k přístupu k již zničenému jedináčkovi
|
||
|
throw std::runtime_error("Access to dead reference of an object.");
|
||
|
}
|
||
|
}
|
||
|
return *_instance;
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
/**
|
||
|
* \brief Funkce zpřístupňující instanci hostující třídy.
|
||
|
*/
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
template<class Host, class ThreadingModel>
|
||
|
Host& cStaticSingleton<Host, ThreadingModel>::Access()
|
||
|
{
|
||
|
return *_instance;
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
// Jedináčkova data
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
template<class Host, class TM>
|
||
|
Host* cStaticSingleton<Host, TM>::_instance = 0;
|
||
|
|
||
|
template<class H, class TM>
|
||
|
bool cStaticSingleton<H, TM>::_destroyed = false;
|
||
|
|
||
|
template<class H, class TM> typename cStaticSingleton<H, TM>::access_function
|
||
|
cStaticSingleton<H, TM>::_access = &cStaticSingleton<H, TM>::Create;
|
||
|
|
||
|
template<class H, class ThreadingModel> typename ThreadingModel::mutex
|
||
|
cStaticSingleton<H, ThreadingModel>::_mutex;
|
||
|
|
||
|
#endif // _STATIC_SINGLETON_HPP_
|