1.用模板实现单例模式
- eg:
P71\Singleton.h
#ifndef _SINGLETON_H
#define _SINGLETON_H
#include <cstdlib>
#include <iostream>
using namespace std;
//将Singleton类模板看成是单例模式类的包装器,用它可以产生单例模式类
//GetInstance返回的不是Singleton自身,而是它所包装的对象T
template <typename T>
class Singleton
{
public:
//方法1:
// static T& GetInstance()//返回的是引用,所以不会调用拷贝构造函数
// {
// static T instance; // 局部静态对象:是在运行期初始化,是有状态的
// return instance; //第2次调用时,会返回先前所初始化的实例,以此来保证单例
// }
//方法2:
//静态成员函数不能调用非静态函数
static T& GetInstance()
{
// pthread_once(Init());//多个线程访问GetInstance时,Init只是调用一次,(3)linux底下推荐使用pthread_once
Init();
return *instance_;
}
/*
static T& GetInstance()这种并不是线程安全的,原因如下:
因为2个线程可能同时调用了GetInstance,2个线程同时进行了if (instance_ == 0)判断,会new2个对象,此时不是线程安全的。
解决办法:
(1)普通锁,不推荐
(2)double check lock双检测锁,不推荐
(3)linux底下推荐使用pthread_once
*/
private:
static void Init()
{
// lock();(1)普通锁
if (instance_ == 0)
{
// //再检测一次
// lock();(2)double check lock双检测锁
// if (instance_ == 0)
// ulock();(2)double check lock双检测锁
instance_ =new T;
//将Destroy函数注册进去,程序结束时,会调用注册的函数(可以注册多个,后注册的函数先调用)
//仅仅注册一次
atexit(Destroy);//单例模式对象销毁推荐使用的方式,而不要使用智能指针
}
// ulock();//(1)普通锁
}
static void Destroy()
{
delete instance_;
}
Singleton(const Singleton& other);
Singleton& operator=(const Singleton& other);
Singleton();
~Singleton();
static T* instance_;
};
template <typename T>
T* Singleton<typename T>::instance_ = 0;//初始化为空指针
#endif //_SINGLETON_H
P71\01.cpp
#include <iotream>
using namespace std;
#include "Singleton.h"
//希望ApplicationImpl类变成单例模式,可以使用模板方式来实现单例模式
class ApplicationImpl
{
public:
ApplicationImpl() {cout<<"ApplicationImpl ..."<<endl;}
~ApplicationImpl() {cout<<"~ApplicationImpl" ...<<endl;}
void Run() {cout<<"Run ..."<<endl;}
};
//将Singleton类模板看成是单例模式类的包装器,用它可以产生单例模式类
//Application是一个单例模式类,不能构造对象
typedef Singleton<ApplicationImpl> Application;
int main(void)
{
// Application a;//Application是一个单例模式类,不能构造对象
Application::GetInstance().Run();
Application::GetInstance().Run();
return 0;
}
- 测试:
两次获取对象,只构造一次,只析构一次,说明获取的是同一个对象。
同一个对象的Run()方法可以调用多次。
2.第36章的动态创建对象改为用模板方式来实现
-
eg:P71\02下面的所有文件
-
测试: