C++ 单例类的实现
来源:互联网 发布:马航mh370阴谋知乎 编辑:程序博客网 时间:2024/05/29 14:32
1. 最优实现
class CSingleton
{
public:
static CSingleton& GetInstance()
{
static CSingleton theSingleton;
return theSingleton;
}
/* more (non-static) functions here */
private:
CSingleton() // 必须定义, 且为private.
{
}
CSingleton(const CSingleton&); // 不实现.
CSingleton& operator=(const CSingleton&); // 不实现.
~CSingleton() // 可声明为public, 但这里声明为private没有错, 可被调用.
{
}
};
2. 其它实现
class CSingleton:
{
public:
static CSingleton* GetInstance()
{
if (!m_pInstance)
{
m_pInstance = new CSingleton;
}
return m_pInstance;
}
/* more (non-static) functions here */
private:
CSingleton() // 必须定义, 且为private.
{
}
static CSingleton* m_pInstance;
class CGarbo // 它的唯一工作就是在析构函数中删除CSingleton的实例.
{
public:
~CGarbo()
{
if (CSingleton::m_pInstance)
{
delete CSingleton::m_pInstance;
}
}
};
static CGarbo m_garbo; // 定义一个静态成员, 在程序结束时, 系统会调用它的析构函数.
};
CSingleton* CSingleton::m_pInstance = NULL; // 这句必须有.
==2============================================
C++中的单例模式
单例模式很有用,使用单例模式,保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。
但是在程序的开发过程中我们总是遇到一些问题,而这些问题主要集中在单例类的消毁过程中,普通使用的单例模式的类如下:
class Singleton:
{
// 其它成员
public:
static Singleton * GetInstance()
{
if (m_pInstance == NULL)
m_pInstance = new Singleton();
return m_pInstance;
}
private:
Singleton(){};
static Singleton * m_pInstance;
}
可是这个类在什么时候调用它的析构函数呢,我们怎么消毁它。提供一个公用的destroy函数来进行它的消毁吗,这很不美观。最后我就在网上找到了如果下的代码处理了这个问题:
class Singleton:
{
// 其它成员
public:
static Singleton * GetInstance(){...}
private:
Singleton(){};
static Singleton * m_pInstance;
class CGarbo // 它的唯一工作就是在析构函数中删除Singleton的实例
{
public:
~CGarbo(){
if (Singleton::m_pInstance)
delete Singleton::m_pInstance;
}
};
static CGarbo Garbo; // 定义一个静态成员,在程序结束时,系统会调用它的析构函数
}
这是非常好的方法,静态成员对象 Garbo 在析构时会自动的消毁单例,我们不用再担心这个问题了。
但是添加一个类的静态对象,总是让人不太满意,所以有人用如下方法来重现实现单例和解决它相应的问题,代码如下:
class Singleton:
{
// 其它成员
public:
static Singleton &GetInstance(){
static Singleton instance;
return instance;
}
private:
Singleton(){};
}
使用局部静态变量,非常强大的方法,完全实现了单例的特性,而且代码量更少,也不用担心单例消毁的问题。
在后期的项目中我全使用了这种方法,可是在项目的开发过程中还是出现了问题,当如下方法使用单例时问题来了,
Singleton singletion = Singleto::GetInstance();
这么做就产生了一个类拷贝的问题,这就为背了单例的特性。
产生这个问题的原因在于,编译器会为类生成一个默认的构造函数,来支持类的拷贝。
最后没有办法,我们要禁止类拷贝和类赋值,禁止程序员用这种方式来使用单例,当时领导的意思是GetInstance()函数返回一个指针而不是返回一个引用,函数代码改为如下:
static Singleton *GetInstance(){
static Singleton instance;
return &instance;
}
可我总是感觉不好,为什么不让编译器不这么干呢。这时我才想起可以显式的声明类拷贝的构造函数,和重载=操作符,新的单例类如下:
class Singleton:
{
// 其它成员
public:
static Singleton &GetInstance(){
static Singleton instance;
return instance;
}
private:
Singleton(){};
Singleton(const Singleton&);
Singleton & operate = (const Singleton&);
}
关于Singleton(const Singleton&);和Singleton & operate = (const Singleton&);函数,我们要声明成私用的,并且只声明不实现。这样子后如果用上面的方式来使用单例时,不管是在友元类中还是其它的,编译器都是报错。
不知道这样的单例类是否还会有问题,但在程序中这样子使用已经基本没有问题了。
==3============================================
单例模式的C++实现
Singleton Constructor
ton1 var = 20
ton2 var = 150 当我们要让一个类产生同一个对象对客户端服务的时候,比如管理数据库连接,管理文件IO等,这时我们就要使用到单例模式。下面是该模式的C++实现(注泽说明)
#include <iostream>
using namespace std;
//单例类的C++实现
class Singleton
{
private:
Singleton();//注意:构造方法私有
virtual ~Singleton();
static Singleton* instance;//惟一实例
int var;//成员变量(用于测试)
public:
static Singleton* GetInstance();//工厂方法(用来获得实例)
int getVar();//获得var的值
void setVar(int);//设置var的值
};
//构造方法实现
Singleton::Singleton()
{
this->var = 20;
cout<<"Singleton Constructor"<<endl;
}
Singleton::~Singleton()
{
delete instance;
}
//初始化静态成员
Singleton* Singleton::instance=new Singleton();
Singleton* Singleton::GetInstance()
{
return instance;
}
//seter && getter含数
int Singleton::getVar()
{
return this->var;
}
void Singleton::setVar(int var)
{
this->var = var;
}
//main
int main(int argc, char* argv[])
{
Singleton *ton1 = Singleton::GetInstance();
Singleton *ton2 = Singleton::GetInstance();
cout<<"ton1 var = "<<ton1->getVar()<<endl;
ton1->setVar(150);
cout<<"ton2 var = "<<ton2->getVar()<<endl;
return 0;
}
输出如下:
Singleton Constructor
ton1 var = 20
ton2 var = 150
在输出结果中我们可以看到,构造方法只调用了一次,ton1与ton2是指向同一个对象的。
From: http://hi.baidu.com/gaogaf/blog/item/10c5d3c880b7df1c7f3e6f2f.html
- [C/C++]汉诺塔的实现
- objective-c 单例类的简单实现
- 堆栈的C实现
- C的类实现
- c库函数的实现
- c实现的urlencode
- Base64的 c实现
- C实现的泛型栈
- 哈希表的C实现
- C中泛型的实现
- 哈希表的C实现
- C实现的五子棋
- C实现的俄罗斯方块
- C泛型栈的实现
- C 实现的Music
- c 双链表的实现
- 单链表的C实现
- 栈的C实现
- 【转载】常用数据类型使用转换详解
- 忆龙2009:iMC iCC配置下发失败的常见原因
- crontab实例+详解 (附:freebsd每天6点重启)
- 忆龙2009:如何清除iMC中所有告警
- JSP轻松入门
- C++ 单例类的实现
- 如何配置和重建Oracle 10G的em服务--dbcontrol
- STL-sort invalid operator< 异常处理(转载)
- 基于J2ME的MD5算法类代码
- Ubuntu添加开机自动启动程序的方法
- windows内核下的一些东西
- [转]DHCP、DHCP中继通信过程
- oracle 触发器的种类和触发事件,DML触发器,DDL事件触发器,替代触发器,查看触发器
- struts-config.xml中的元素有严格的顺序