一个比较完善的C++ Singleton模式类

转载地址:http://hi.baidu.com/uxufgfwvmhfitzr/item/6fd0b82f49aa1fd5a417b630


------------------------------目录------------------------------ 

本文的主要内容为: 
1、Singleton模式的基类 
2、基本的Singleton容器 
3、Singleton模板 
4、引入线程保护代码 
5、完整的代码 
6、如何使用 

------------------------------Singleton模式的基类------------------------------ 
1、Singleton模式的基类 
首先需要统一Singleton类家族的风格,我们用宏定义全权实现构造函数、析构函数和静态的GetInstance()函数。但每一个Singleton也许有其自己的个性,在构造和析构的时候,可能会有额外的操作,我们将其延伸至以下两个纯虚函数中来,由每个Singleton类自己去完成。 
class SinglePattern 

protected: 
virtual void InitialInstance() = 0; 
virtual void DisposeInstance() = 0; 
}; 

------------------------------基本的Singleton容器------------------------------ 
2、基本的Singleton容器 
我们使用auto_ptr来管理指针,使之在程序结束时会正确的得到析构。 
以下为基本的一个Singleton容器,其所容指针即为自己的一个实例。 
class Singleton 

friend class auto_ptr<Singleton>; 
protected: 
static auto_ptr<Singleton> m_Instance; 
protected: 
__fastcall Singleton(){}; 
virtual ~Singleton(){}; 
public: 
static Singleton* __fastcall GetInstance() 

if(m_Instance.get() == NULL) 

m_Instance.reset(new Singleton()); 

return m_Instance.get(); 

}; 
auto_ptr<Singleton> Singleton::m_Instance; 

------------------------------Singleton模板------------------------------ 
3、Singleton模板 
如果我们对每一个Singleton类都向上面所写那样,我们需要做很多重复工作。现在我们使用模板类来包装一下。 
我们只需要将上面的代码,用auto_ptr管理的指针改成模板代码即可,程序代码如下: 
template <class T> 
class Singleton 

friend class auto_ptr<T>; 
protected: 
static auto_ptr<T> m_Instance; 
protected: 
__fastcall Singleton(){}; 
virtual ~Singleton(){}; 
public: 
static T* __fastcall GetInstance() 

if(m_Instance.get() == NULL) 

m_Instance.reset(new T()); 

return m_Instance.get(); 

}; 
template<class T> 
auto_ptr<T> Singleton<T>::m_Instance; 

实际上你可以看见,如果编写Singleton<Singleton>即变成了基本的Singleton。 

------------------------------引入线程保护代码------------------------------ 
4、引入线程保护代码 
上面的代码在单线程中可以很好的工作,但在多线程环境中,会产生实例被析构再构造的假Singleton类。这里我只引入一个简单的线程保护代码做个示例: 
class CResGuard 

public: 
CResGuard() { m_lGrdCnt = 0; InitializeCriticalSection(&m_cs); } 
~CResGuard() { DeleteCriticalSection(&m_cs); } 
// IsGuarded is used for debugging 
BOOL IsGuarded() const { return(m_lGrdCnt > 0); } 
public: 
class CGuard { 
public: 
CGuard(CResGuard& rg) : m_rg(rg) { m_rg.Guard(); }; 
~CGuard() { m_rg.Unguard(); } 
protected: 
CResGuard& m_rg; 
}; 
private: 
void Guard() { EnterCriticalSection(&m_cs); m_lGrdCnt++; } 
void Unguard() { m_lGrdCnt--; LeaveCriticalSection(&m_cs); } 

// Guard/Unguard can only be accessed by the nested CGuard class. 
friend class CResGuard::CGuard; 
private: 
CRITICAL_SECTION m_cs; 
long m_lGrdCnt; // # of EnterCriticalSection calls 
}; 

------------------------------完整的代码------------------------------ 
5、完整的代码 
以下是完整的代码,在C++Builder 6, Windows XP编译通过。 
#pragma once 
#include <Windows.h> 
#include <memory> //线程安全使用的头文件 
#ifndef SingletonH 
#define SingletonH 

using namespace std; 

// Base SinglePattern Class 
class SinglePattern 

protected: 
virtual void InitialInstance() = 0; 
virtual void DisposeInstance() = 0; 
}; 

// Thread Safe Class 
class CResGuard 

public: 
CResGuard() { m_lGrdCnt = 0; InitializeCriticalSection(&m_cs); } 
~CResGuard() { DeleteCriticalSection(&m_cs); } 
// IsGuarded is used for debugging 
BOOL IsGuarded() const { return(m_lGrdCnt > 0); } 
public: 
class CGuard { 
public: 
CGuard(CResGuard& rg) : m_rg(rg) { m_rg.Guard(); }; 
~CGuard() { m_rg.Unguard(); } 
protected: 
CResGuard& m_rg; 
}; 
private: 
void Guard() { EnterCriticalSection(&m_cs); m_lGrdCnt++; } 
void Unguard() { m_lGrdCnt--; LeaveCriticalSection(&m_cs); } 

// Guard/Unguard can only be accessed by the nested CGuard class. 
friend class CResGuard::CGuard; 
private: 
CRITICAL_SECTION m_cs; 
long m_lGrdCnt; // # of EnterCriticalSection calls 
}; 

// Singleton Container 
template <class T> 
class Singleton 

friend class auto_ptr<T>; 
protected: 
static auto_ptr<T> m_Instance; 
static CResGuard _rs; 
protected: 
__fastcall Singleton(){}; 
virtual ~Singleton(){}; 
public: 
static T* __fastcall GetInstance() 

CResGuard::CGuard gd(_rs); 
if(m_Instance.get() == NULL) 

m_Instance.reset(new T()); 

return m_Instance.get(); 

}; 
template <class T> 
CResGuard Singleton<T>::_rs; 
template<class T> 
auto_ptr<T> Singleton<T>::m_Instance; 

// MACRO of Singleton Pattern to use 
#define DECLARE_SINGLETON(type) \ 
friend class auto_ptr<type>; \ 
friend class Singleton<type>; \ 
public: \ 
static type *GetInstance() \ 
{ \ 
return Singleton<type>::GetInstance(); \ 
} \ 
protected: \ 
__fastcall type() \ 
{ \ 
InitialInstance(); \ 
} \ 
public: \ 
virtual ~type() \ 
{ \ 
DisposeInstance(); \ 

#endif 

------------------------------如何使用------------------------------ 
6、如何使用 
在你自己需要实现Singleton模式的类,使用宏定义,并实现两个纯虚函数,即可。 
以下为一个使用示例: 
class MySingle : public SinglePattern 

DECLARE_SINGLETON(MySingle) 
protected: 
virtual void InitialInstance(){} 
virtual void DisposeInstance(){} 
public: 
void Run(){}; 
}; 

int main(int argc, char* argv[]) 

MySingle::GetInstance()->Run(); 
return 0; 
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单例模式是一种设计模式,它保证一个只有一个实例,并提供全局访问点。在C语言中,可以通过静态变量和函数来实现单例模式。 下面是一个继承单例模式的示例代码: ```c #include <stdio.h> // 基 typedef struct { int value; } Singleton; // 全局唯一实例 static Singleton *instance = NULL; // 获取实例的函数 Singleton *get_instance() { if (instance == NULL) { // 第一次调用时创建实例 instance = (Singleton *) malloc(sizeof(Singleton)); instance->value = 0; } return instance; } // 继承自基的子 typedef struct { Singleton base; // 基的实例作为子的成员变量 int extra_value; } SubSingleton; // 全局唯一子实例 static SubSingleton *sub_instance = NULL; // 获取子实例的函数 SubSingleton *get_sub_instance() { if (sub_instance == NULL) { // 第一次调用时创建子实例 sub_instance = (SubSingleton *) malloc(sizeof(SubSingleton)); sub_instance->base = *get_instance(); // 基实例的值拷贝给子实例 sub_instance->extra_value = 0; } return sub_instance; } int main() { // 获取基实例并修改值 Singleton *instance1 = get_instance(); instance1->value = 10; printf("instance1 value: %d\n", instance1->value); // 再次获取基实例,应该和上一个实例是同一个 Singleton *instance2 = get_instance(); printf("instance2 value: %d\n", instance2->value); // 获取子实例并修改值 SubSingleton *sub_instance1 = get_sub_instance(); sub_instance1->extra_value = 5; printf("sub_instance1 value: %d, extra_value: %d\n", sub_instance1->base.value, sub_instance1->extra_value); // 再次获取子实例,应该和上一个实例是同一个 SubSingleton *sub_instance2 = get_sub_instance(); printf("sub_instance2 value: %d, extra_value: %d\n", sub_instance2->base.value, sub_instance2->extra_value); // 子实例和基实例应该是同一个 printf("sub_instance2 base value: %d\n", sub_instance2->base.value); return 0; } ``` 在上面的代码中,基Singleton定义了一个整数成员变量value,并通过get_instance函数实现单例模式。子SubSingleton继承自基,并添加了一个额外的整数成员变量extra_value。通过get_sub_instance函数实现子的单例模式。 在main函数中,首先获取基实例并修改value的值,然后再次获取基实例,验证它们是同一个实例。接着获取子实例并修改extra_value的值,然后再次获取子实例,验证它们是同一个实例,并且子实例和基实例是同一个实例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值