代码:
// Test_Console.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <iomanip>
#include <fstream>
#include<cstdlib>
#include<string>
#include<mutex>
using namespace std;
template <typename T>
class Singleton
{
public:
template<typename Args>
// 全局访问点 Instance
static T& Instance(Args&& args){ // 使用引用来代替指针,防止外部通过 delete 来销毁实例
// 如果已经存在实例则直接返回
if (m_pInstance == nullptr){
// 生成新实例
m_pInstance = new T(forward<Args>(args));
}
return *m_pInstance;
}
static T& GetInstance(){
// 如果已经存在实例则直接返回
if (m_pInstance == nullptr)
throw::logic_error("请先初始化实例");
return *m_pInstance;
}
static void DestroyInstance(){
delete m_pInstance;
m_pInstance = nullptr;
}
private:
Singleton(void); // 禁止外部使用构造函数,防止外部生成新实例
virtual ~Singleton(void); // 禁止外部使用析构函数
Singleton(const Singleton&); // 禁止外部使用拷贝函数,防止外部生成新实例
Singleton& operator=(const Singleton&); // 禁止外部使用赋值函数,防止外部生成新实例
static T* m_pInstance; // 声明 Singleton 实例,使用指针解决多线程安全问题
};
template<class T> T* Singleton<T>::m_pInstance = nullptr; // Singleton 实例赋值
// 测试类
struct A
{
A(const string&) { cout << "A(const string&)" << endl; }
A(string&& x) { cout << "A(string&& x)" << endl; }
void Fun() { cout << "Fun()" << endl; }
};
int _tmain(int argc, _TCHAR* argv[])
{
//Singleton s1; // 语法错误(将构造函数设置为 private)
string str = "x";
Singleton<A>::Instance(str);
Singleton<A>::Instance(move(str));
Singleton<A>::GetInstance().Fun();
Singleton<A>::DestroyInstance();
cout << "------------------" << endl;
Singleton<A>::Instance(move(str));
Singleton<A>::GetInstance().Fun();
Singleton<A>::DestroyInstance();
getchar();
return 0;
}
效果图: