从 C 向 C++ 进阶系列导航
1. 单例模式类
单例模式类的含义是在整个程序生命周期中,只能存在一个对象。那么怎么限定编译器只能生成一个类对象呢?我们可以借用 static 成员的全局特性,作为是否已存在类对象的标志。具体实现方法是:将构造函数的访问属性设置为 private,定义 symbol 并初始化为 NULL;当需要使用对象时,先访问 symbol 的值,如果是空值,那么便创建对象并置位 symbol 标记,如果是非空值,返回 symbol 标记的对象。
- 实验:
class Test
{
private:
static Test* symbol;
Test(){}
public:
static Test* GetObj();
void Print();
};
Test* Test::symbol = NULL;
void Test::Print()
{
cout << "this = " << this << endl;
}
Test* Test::GetObj()
{
if( symbol == NULL )
{
symbol = new Test;
}
return symbol;
}
int main()
{
// Test obj; // error: ‘Test::Test()’ is private
Test* p_A = Test::GetObj();
Test* p_B = Test::GetObj();
Test* p_C = Test::GetObj();
p_A->Print(); // this = 0xbcdc20
p_B->Print(); // this = 0xbcdc20
p_C->Print(); // this = 0xbcdc20
return 0;
}
2. 单例模式类模版
我们可以把单例模式类中的核心思想部分提取出来,封装成模板,这样子当某个类需要作为单例类时,直接声明类模板为友元即可。
- 实验:
/* singleton.h */
#ifndef _SINGLETON_H_
#define _SINGLETON_H_
template <typename T>
class Singleton
{
private:
static T* symbol;
public:
static T* GetObj();
};
template <typename T>
T* Singleton<T>::symbol = NULL;
template <typename T>
T* Singleton<T>::GetObj()
{
if( symbol == NULL )
{
symbol = new T;
}
return symbol;
}
#endif
/* main.c */
#include <iostream>
#include "singleton.h"
using namespace std;
class Test
{
private:
friend class Singleton<Test>;
Test(){}
public:
void Print();
};
void Test::Print()
{
cout << "this = " << this << endl;
}
int main()
{
Test* p_A = Singleton<Test>::GetObj();
Test* p_B = Singleton<Test>::GetObj();
p_A->Print(); // this = 0x1b30c20
p_B->Print(); // this = 0x1b30c20
return 0;
}