定义:在某些情况下,我们设计中的对象只需要一个,比方说:线程池(threadpool)、缓存(cache)、对话框、处理偏好设置和注册表对象、日志对象、充当打印机、显卡等设备的驱动程序的对象等。事实上,这类对象只能有一个实例,如果制造出多个实例,就会导致许多问题产生。
这里要说的单件模式就能确保一个类只有一个实例,并提供一个全局访问点。
在C++中实现如下:
实现1:
 #include <iostream>
using namespace std; class CSingleton
{
public:
static CSingleton* getInstance();
static void cleanInstance();
int getValue();
void setValue(int iValue);
private:
int m_iValue;
static CSingleton* m_pSingleton;
CSingleton();
~CSingleton();
}; CSingleton* CSingleton::m_pSingleton = NULL; CSingleton::CSingleton()
{
cout << "Constructor" << endl;
} CSingleton::~CSingleton()
{
cout << "Destructor" << endl;
} CSingleton* CSingleton::getInstance()
{
if (NULL == m_pSingleton)
{
m_pSingleton = new CSingleton();
}
return m_pSingleton;
} void CSingleton::cleanInstance()
{
delete m_pSingleton; m_pSingleton = NULL;
} int CSingleton::getValue()
{
return m_iValue;
} void CSingleton::setValue(int iValue)
{
m_iValue = iValue;
} int main()
{
CSingleton* pSingleton1 = CSingleton::getInstance();
CSingleton* pSingleton2 = CSingleton::getInstance();
pSingleton1->setValue();
if (pSingleton1->getValue() == pSingleton2->getValue())
{
cout << "Two objects is the same instance" << endl;
}
else
{
cout << "Two objects isn't the same instance" << endl;
} CSingleton::cleanInstance();
return ;
}

相信大多数的同仁都喜欢使用上边这种单件模式的实现方法,如果在单线程的情况下,是没有问题的,但如果是多线程,那么就极有可能会返回两个不同的对象,在调用CSingleton::getInstance的时候,两个线程如果都同时运行完if判断,而又还没有调用到构造函数的话,想象下后果吧。那该怎么办呢?看下边这个实现吧。

实现2:
 #include <iostream>
using namespace std; class CSingleton
{
public:
static CSingleton* getInstance();
static void cleanInstance();
int getValue();
void setValue(int iValue);
private:
int m_iValue;
static CSingleton* m_pSingleton;
CSingleton();
~CSingleton();
}; // 在进程运行开始就实例化该单件,又称“急切”创建实例
CSingleton* CSingleton::m_pSingleton = new CSingleton(); CSingleton::CSingleton()
{
cout << "Constructor" << endl;
} CSingleton::~CSingleton()
{
cout << "Destructor" << endl;
} CSingleton* CSingleton::getInstance()
{
return m_pSingleton;
} void CSingleton::cleanInstance()
{
delete m_pSingleton; m_pSingleton = NULL;
} int CSingleton::getValue()
{
return m_iValue;
} void CSingleton::setValue(int iValue)
{
m_iValue = iValue;
} int main()
{
CSingleton* pSingleton1 = CSingleton::getInstance();
CSingleton* pSingleton2 = CSingleton::getInstance();
pSingleton1->setValue();
if (pSingleton1->getValue() == pSingleton2->getValue())
{
cout << "Two objects is the same instance" << endl;
}
else
{
cout << "Two objects isn't the same instance" << endl;
} CSingleton::cleanInstance();
return ;
}
哈哈,看清楚了吗?就是在进程运行的时候就对这个单件进行实例化,可是这样似乎又不能达到延迟实例化的目的啦。如果我们的对象对资源占用非常大,而我们的进行在整个过程中其实并没有用到这个单件,那岂不是白白浪费资源了嘛。还有更好的办法。
实现3:
 #include <iostream>
using namespace std; class CSingleton
{
public:
static CSingleton* getInstance();
int getValue();
void setValue(int iValue);
private:
int m_iValue;
CSingleton();
~CSingleton();
}; CSingleton::CSingleton()
{
cout << "Constructor" << endl;
} CSingleton::~CSingleton()
{
cout << "Destructor" << endl;
} CSingleton* CSingleton::getInstance()
{
static CSingleton single;
return &single;
} int CSingleton::getValue()
{
return m_iValue;
} void CSingleton::setValue(int iValue)
{
m_iValue = iValue;
} int main()
{
cout << "Process begin" << endl;
CSingleton* pSingleton1 = CSingleton::getInstance();
CSingleton* pSingleton2 = CSingleton::getInstance();
pSingleton1->setValue();
if (pSingleton1->getValue() == pSingleton2->getValue())
{
cout << "Two objects is the same instance" << endl;
}
else
{
cout << "Two objects isn't the same instance" << endl;
}
return ;
}
看下运行结果吧:

Process begin
Constructor
Two objects is the same instance
Destructor

是不是跟预想的一样呢?把单件声明为成员函数中的静态成员,这样既可以达到延迟实例化的目的,又能达到线程安全的目的,而且看结果的最后,是不是在程序退出的时候,还自动的调用了析构函数呢?这样我们就可以把资源的释放放到析构函数里边,等到程序退出的时候,进程会自动释放这些静态成员的。

C++单例模式实例的更多相关文章

  1. 单例模式实例&多线程应用

    单例模式是指:对于一个类在内存中只能存在唯一一个对象,这种设计模式叫做单例设计模式. 单例设计模式的写法: 1. 设置私有(private)的构造方法. 2. 实例化一个该类的对象作为成员变量,并设置 ...

  2. java单例模式实例

    什么是单例模式? 定义:确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例场景,也就是说:确保某个类有且只有一个对象的场景,避免产生多个对象消耗过多的资源,或者某种类型的对象应该有且只有一 ...

  3. php设计模式之单例模式实例(设计mysqli连接数据的数据处理类)

    一直在研究php的设计模式,但是没有亲历使用过,所以还是一知半解,通过几天的学习终于对php的单例设计模式稍稍的有些了解,特此写出一个数据库处理类(只涉及到简单的原理),以便自己以后方便查阅,至于其他 ...

  4. PHP单例模式实例,连接数据库对类的引用

    <?php//单例模式连接数据库class pzhang{ static private $instance; private static $config; private $dbase = ...

  5. Javascript单例模式概念与实例

    前言 和其他编程语言一样,Javascript同样拥有着很多种设计模式,比如单例模式.代理模式.观察者模式等,熟练运用Javascript的设计模式可以使我们的代码逻辑更加清晰,并且更加易于维护和重构 ...

  6. 单例模式(Singleton)(单一实例)

    单例模式基本要点: 用于确保一个类只有一个实例,并且这个实例易于被访问. 让类自身负责保存他的唯一实例.这个类可以保证没有其他实例创建,并且他可以提供一个访问实例的方法,来实现单例模式. (1)把构造 ...

  7. php设计模式--单例模式

    单例模式(Singleton Pattern 单件模式或单元素模式) 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 单例模式是一种常见的设计模式,在计算机系统中,线程池.缓 ...

  8. 设计模式(java) 单例模式 单例类

    ·单例类 单实例类,就是这个类只能创建一个对象,保证了对象实例的唯一性. 1.单例模式( Singleton Pattern) 是一个比较简单的模式, 其定义如下:Ensure a class has ...

  9. Python设计模式之单例模式

    1.由于语言的特性不同,设计模式的实现方式和实现难度也会不同 2.有的模式已经在语言内置了,比如迭代器模式. 3.单例模式可以直接用模块级变量来实现 4.普通工厂模式可以直接通过传入"类名& ...

随机推荐

  1. GetOpenFileName 选择文件夹的解决方法

    某些环境下(如WIN PE)windows自带的选择文件夹api不能使用或者体验不佳.现在利用GetOpenFileName的回掉参数实现了选择文件夹选择功能. #include <Window ...

  2. python基础教程总结6——类

    1. 如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法. 类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义: class  ...

  3. HDU 4738 Caocao's Bridges taijan (求割边,神坑)

    神坑题.这题的坑点有1.判断连通,2.有重边,3.至少要有一个人背*** 因为有重边,tarjan的时候不能用子结点和父节点来判断是不是树边的二次访问,所以我的采用用前向星存边编号的奇偶性关系,用^1 ...

  4. 【转】iOS学习笔记(十五)——数据库操作(SQLite)

    SQLite (http://www.sqlite.org/docs.html) 是一个轻量级的关系数据库.SQLite最初的设计目标是用于嵌入式系统,它占用资源非常少,在嵌入式设备中,只需要几百K的 ...

  5. 2018.2.12 PHP 如何读取一亿行的大文件

    PHP 如何读取一亿行的大文件 我们可能在很多场景下需要用 PHP 读取大文件,之后进行处理,如果你没有相关的经验可以看下,希望能给你带来一些启发. 模拟场景 我们有一个 1亿 行,大小大概为 3G ...

  6. 利用wget 和 curl 监控网站是否正常

    监控网站URL是否正常最常见的方法莫过于wget和curl命令了,这两个命令都是非常强大,参数也非常多,下面列举几个常用的参数. wget  常用命令参数:--spider              ...

  7. PHP网站实现地址URL重定向

    网站建设中,通常会用到网站地址URL的重定向,这样的好处是有利于你网站的SEO优化,也就是让你的网站实现伪静态,下面简单介绍一下实现的两种方法: 1.在Apache配置文件中设置重定向 首先找到Apa ...

  8. Yii2.0 的安装学习

    视频学习地址: 后盾网视频: http://www.houdunren.com/houdunren18_lesson_76?vid=7350 与<Yii框架>不得不说的故事—基础篇 htt ...

  9. stm32L0工程建立(HAL+IAR,无cubemx)

    https://files.cnblogs.com/files/CodeWorkerLiMing/STM32HAL%E5%BA%93%E5%AD%A6%E4%B9%A0%E2%80%94%E5%B7% ...

  10. 字符串:HDU3064-最长回文

    最长回文 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Descri ...