单例极致 singleton

 王子原创作品。转载请注明出处http://blog.csdn.net/wang19840301

一、四种常见的单例:

1、没有构造函数(DEFINE_SINGLETON_DEFAULT);

2、有构造函数,构造函数没有参数(DEFINE_SINGLETON_CONSTRUCT_NO_PARAM);

3、有构造函数,构造函数有没有参数版本(DEFINE_SINGLETON_CONSTRUCT_WITH_DEFAULT);

4、有构造函数,构造函数都有参数(DEFINE_SINGLETON_CONSTRUCT);

通过宏定义巧妙实现,使用也很方便!


二、调用代码如下:

#include "stdafx.h"
#include "Singleton.h"


class MyClass1
{
DEFINE_SINGLETON_DEFAULT(MyClass1);
public:
void f() { printf("My class 1 function\n"); };
};


class MyClass2
{
DEFINE_SINGLETON_CONSTRUCT_NO_PARAM(MyClass2);
public:
void f() { printf("My class 2 function\n"); };
};
MyClass2::MyClass2() { }


class MyClass3
{
DEFINE_SINGLETON_CONSTRUCT_WITH_DEFAULT(MyClass3);
private:
MyClass3(int a = 3) { a_ = a; }
int a_;
public:
void f() { printf("My class 3 function, a=%d\n", a_); };
};


class MyClass4
{
DEFINE_SINGLETON_CONSTRUCT(MyClass4);
private:
MyClass4(int a) { a_ = a; }
int a_;
public:
void f() { printf("My class 4 function, a=%d\n", a_); };
};


int _tmain(int argc, char* argv[])
{
MyClass1::singleton::GetInstance()->f();
MyClass2::singleton::GetInstance()->f();


//MyClass3::singleton::GetInstance()->f(); // normal
MyClass3::singleton::Create(8);
MyClass3::singleton::GetInstance()->f();


//MyClass4::singleton::GetInstance()->f(); // error
MyClass4::singleton::Create(18);
MyClass4::singleton::GetInstance()->f();


system("pause");
}

注意:

1、MyClass3类可以不用调用Create方法,而直接调用MyClass3::singleton::GetInstance()->f()方法。这种情况下会调用无参构造函数;

2、MyClass4类必须调用Create方法初始化,否则会报内存错误;


三、singleton源代码如下:

#pragma once
#include <mutex>


namespace klicen 
{
namespace utils 
{
class noncopyable
{
protected:
noncopyable() = default;
~noncopyable() = default;
noncopyable(const noncopyable&) = delete;
noncopyable& operator=(const noncopyable&) = delete;
};


template <typename T>
class Singleton : private noncopyable
{
public:
static T* GetInstance()
{
// double check
if (nullptr == instance_)
{
std::lock_guard<std::mutex> lock(mutex_);
if (nullptr == instance_)
{
instance_ = new T;
}
}
return instance_;
}
private:
Singleton();
static T* instance_;
static std::mutex mutex_;
};
template <typename T> T* Singleton<T>::instance_ = nullptr;
template <typename T> std::mutex Singleton<T>::mutex_;
#define DEFINE_SINGLETON_DEFAULT(class_name); \
public: \
friend class klicen::utils::Singleton<class_name>; \
typedef klicen::utils::Singleton<class_name> singleton; \
private: \
class_name() {} \
virtual ~class_name() {} \
class_name(const class_name&){} \
class_name& operator=(const class_name&){} 


template <typename T>
class SingletonConstruct : private noncopyable
{
public:
static T* GetInstance()
{
/*if (nullptr == instance_)
{
std::lock_guard<std::mutex> lock(mutex_);
if (nullptr == instance_)
{
throw std::exception("Get singleton failed");
}
}*/
return instance_;
}
template <typename... Args>
static void Create(Args&&... args)
{
if (nullptr == instance_)
{
std::lock_guard<std::mutex> lock(mutex_);
if (nullptr == instance_)
{
instance_ = new T(std::forward<Args>(args)...);
}
}
}
private:
SingletonConstruct();
static T* instance_;
static std::mutex mutex_;
};
template <typename T> T* SingletonConstruct<T>::instance_ = nullptr;
template <typename T> std::mutex SingletonConstruct<T>::mutex_;
#define DEFINE_SINGLETON_CONSTRUCT(class_name); \
public: \
friend class klicen::utils::SingletonConstruct<class_name>; \
typedef klicen::utils::SingletonConstruct<class_name> singleton; \
private: \
virtual ~class_name() {} \
class_name& operator=(const class_name&){} 


template <typename T>
class SingletonConstructNoParam : private noncopyable
{
public:
static T* GetInstance()
{
if (nullptr == instance_)
{
std::lock_guard<std::mutex> lock(mutex_);
if (nullptr == instance_)
{
instance_ = new T;
}
}
return instance_;
}
private:
SingletonConstructNoParam();
static T* instance_;
static std::mutex mutex_;
};
template <typename T> T* SingletonConstructNoParam<T>::instance_ = nullptr;
template <typename T> std::mutex SingletonConstructNoParam<T>::mutex_;
#define DEFINE_SINGLETON_CONSTRUCT_NO_PARAM(class_name); \
public: \
friend class klicen::utils::SingletonConstructNoParam<class_name>; \
typedef klicen::utils::SingletonConstructNoParam<class_name> singleton; \
private: \
class_name(); \
virtual ~class_name() {} \
class_name& operator=(const class_name&){} 


template <typename T>
class SingletonConstructWithDefault : private noncopyable
{
public:
static T* GetInstance()
{
if (nullptr == instance_)
{
std::lock_guard<std::mutex> lock(mutex_);
if (nullptr == instance_)
{
instance_ = new T;
}
}
return instance_;
}
template <typename... Args>
static void Create(Args&&... args)
{
if (nullptr == instance_)
{
std::lock_guard<std::mutex> lock(mutex_);
if (nullptr == instance_)
{
instance_ = new T(std::forward<Args>(args)...);
}
}
}
private:
SingletonConstructWithDefault();
static T* instance_;
static std::mutex mutex_;
};
template <typename T> T* SingletonConstructWithDefault<T>::instance_ = nullptr;
template <typename T> std::mutex SingletonConstructWithDefault<T>::mutex_;
#define DEFINE_SINGLETON_CONSTRUCT_WITH_DEFAULT(class_name); \
public: \
friend class klicen::utils::SingletonConstructWithDefault<class_name>; \
typedef klicen::utils::SingletonConstructWithDefault<class_name> singleton; \
private: \
virtual ~class_name() {} \
class_name& operator=(const class_name&){} 
} // namespace utils
} // namespace klicen


下载地址:http://download.csdn.net/detail/wang19840301/8842119

猜你喜欢

转载自blog.csdn.net/wang19840301/article/details/46650883