定义:在某些情况下,我们设计中的对象只需要一个,比方说:线程池(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. 10款免费的MySQL数据库图形化管理工具

    绝大多数的关系数据库都明显不同于MS Access,它们都有两个截然不同的部分:后端作为数据仓库,前端作为用于数据组件通信的用户界面.这种设计非常巧妙,它并行处理两层编程模型,将数据 层从用户界面中分 ...

  2. 监控服务端口状态python脚本

    #!/usr/bin/python import socket,os,time data={ 8080:"tomcat9", 18080:"tomcat_hjgdmj&q ...

  3. WINDOWS-基础:SafeArray的使用方法

    1 SafeArray的作用 使用SafeArray SafeArray是VB中的数组存储方式.通过SafeArray,可以在VC++和VB间相互调用. SafeArray也是Automation中的 ...

  4. mongodb 导入导出

    F:\Mongodb\bin>mongoexport.exe -h localhost:27017 -d proxy_db -c proxy_tb -o f:/p1.json 导出 -h 服务器 ...

  5. jquery的正则表达式

    正则表达式 位置: ^      开头 $      结尾 次数: *      0或多个 +      1或多个 ?      0或1个 {n}     就是n个 {n,}   至少n个 {n,m} ...

  6. GTA5(侠盗猎车5)中文版破解版

    )中文版破解版迅雷下载地址(使用迅雷新建任务填上地址): magnet:?xt=urn:btih:65F16B126D8A656E4FC825DE204EBFAF04B070FC

  7. Oracle 闪回 找回数据的实现方法

    Oracle 闪回 找回数据的实现方法 闪回技术是Oracle强大数据库备份恢复机制的一部分,在数据库发生逻辑错误的时候,闪回技术能提供快速且最小损失的恢复.这篇文章主要介绍了Oracle 闪回 找回 ...

  8. 【贪心】10.24assassin

    题目分析 没有题目分析…… 寄存一下神奇反悔贪心 #include<bits/stdc++.h> ; struct node { int a,b; node(, ):a(x),b(y) { ...

  9. mysql 在线添加字段

    使用工具pt-online-schema-change #! /bin/bash stime=`date +%s` echo "增加字段开始测试时间为:`date +%H:%M:%S`&qu ...

  10. 通过composer安装阿里大于接口扩展

    # 安装laravel阿里大鱼服务 composer require iscms/alisms-for-laravel laravel配置 # 注册服务 # 在config\app.php文件中找到P ...