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

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 精子形态正常率2怎么办 精子头部畸形率高怎么办 椎底动脉供血不足怎么办 颈椎动脉供血不足怎么办 颈椎病引起头晕脑供血不足怎么办 淘宝店被释放了怎么办 被枣蝎子蛰了怎么办 六角螺丝拧花了怎么办 苹果螺丝滑丝了怎么办 六角螺帽拧花了怎么办 六角螺母拧花了怎么办 内六角螺丝滑丝怎么办 十字螺丝拧花了怎么办 梅花螺丝滑丝了怎么办 螺丝孔道滑丝了,怎么办 锅把铆钉松啦怎么办 膨胀螺丝孔大了怎么办 戒指不圆了怎么办妙招 眼镜框的腿断了怎么办 弹簧腿眼镜坏了怎么办 vps搭建ss被墙怎么办 注塑机螺杆黏料怎么办 分解师耐久度0了怎么办 有鼻涕擤不出来怎么办 擤鼻涕耳朵堵了怎么办 脸用什么都过敏怎么办 1岁宝宝流清鼻涕怎么办 2岁宝宝流清鼻涕怎么办 3岁儿童流清鼻涕怎么办 鼻子老是流清水鼻涕怎么办 5岁儿童感冒鼻塞怎么办 3岁宝宝感冒鼻塞怎么办 宝宝9个月流鼻涕怎么办 鼻涕又黄又粘稠怎么办 鼻子一直流黄水怎么办 宝宝眼屎多又黄怎么办 宝宝痰多鼻涕多怎么办 小孩痰多鼻涕多怎么办 用qq登不了微博怎么办 中国银行u盾丢了怎么办 我的世界遇见him怎么办