您的位置:首页 > 其它

单例极致 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: