单例极致 singleton
2015-06-26 15:44
330 查看
王子原创作品。转载请注明出处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
一、四种常见的单例:
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
相关文章推荐
- [Mysql]备份同库中一张表的历史记录 insert into ..select
- 字符串翻转
- 网络图片查看器
- [Mysql]备份同库中一张表的历史记录 insert into ..select
- NTP配置实践
- server id
- 剑指offer 面试题9
- Node.js程序在node-windows中不能运行
- huawei校招测试题
- 字符串翻转
- Yii2-设置和获取、删除Cookies空值分析
- iOS标准时间与时间戳相互转换
- mongoDB简介及安装
- 大数据の协同过滤——发现新的兴趣点
- H264码流打包分析(精华)
- 顶顶顶
- 发现一个不错的网址,学习mysql配置。
- C++中拷贝(复制)构造函数和赋值运算符重载函数
- stm32 NVIC中断管理实现[直接操作寄存器]
- Java魔法堂:找外援的利器——Runtime.exec详解