设计模式C++学习笔记之三(Singleton单例模式)
单例模式看起来也蛮简单的,就是在系统中只允许产生这个类的一个实例,既然这么简单,就直接贴代码了。更详细的内容及说明可以参考原作者博客:cbf4life.cnblogs.com。
3.1.解释
main(),大臣
CEmperor,需要单例的类
说明:很多大臣拜见的皇帝,只有一个。体现在面向对象方面,CEmperor定义一个静态指针,和一个静态函数,私有化构造函数、析构函数、构造函数复制、重载赋值语句。
注意:线程安全,采用互斥体的方式实现。
看代码:
//Emperor.h
#pragma once
#include <iostream>
using std::cout;
using std::endl;
using std::string;
class CEmperor
{
public:
static CEmperor * GetInstance();
static void ReleaseInstance();
void EmperorInfo(void);
void SetEmperorTag(string tag);
private:
CEmperor(void);
virtual ~CEmperor(void);
CEmperor(const CEmperor&);
CEmperor& operator=(const CEmperor&);
static CEmperor *m_pEmperor;
static HANDLE m_pMutex;
string m_EmperorTag;
class CGarbo
{
public:
CGarbo()
{
cout << "Create Garbo" << endl;
}
~CGarbo()
{
cout << "Destroy Garbo" << endl;
if (NULL != m_pEmperor)
{
WaitForSingleObject(m_pMutex, INFINITE);
if (NULL != m_pEmperor)
{
cout << "Remove instance" << endl;
delete m_pEmperor;
m_pEmperor = NULL;
}
ReleaseMutex(m_pMutex);
}
if (NULL != m_pMutex)
{
cout << "Delete mutex" << endl;
CloseHandle(m_pMutex);
m_pMutex = NULL;
}
}
};
static CGarbo m_Garbo;
};
//Emperor.cpp
#include "StdAfx.h"
#include "Emperor.h"
#include <iostream>
using std::cout;
using std::endl;
using std::string;
CEmperor* CEmperor::m_pEmperor = NULL;
HANDLE CEmperor::m_pMutex = CreateMutex(NULL, FALSE, NULL);
CEmperor::CGarbo CEmperor::m_Garbo;
CEmperor::CEmperor(void)
{
cout << "Create CEmperor Instance" << endl;
}
CEmperor::~CEmperor(void)
{
cout << "Destroy CEmperor Instance and release its resource" << endl;
}
void CEmperor::EmperorInfo(void)
{
char msgBuffer[50] = { 0 };
sprintf_s(msgBuffer, 50, "皇ê帝?某3某3某3... ...(%s).", m_EmperorTag.c_str());
string msg(msgBuffer);
cout << msg.c_str() << endl;
}
CEmperor* CEmperor::GetInstance()
{
if (NULL == m_pEmperor)
{
WaitForSingleObject(m_pMutex, INFINITE);
if (NULL == m_pEmperor)
m_pEmperor = new CEmperor();
ReleaseMutex(m_pMutex);
}
return m_pEmperor;
}
void CEmperor::ReleaseInstance()
{
if (NULL != m_pEmperor)
{
WaitForSingleObject(m_pMutex, INFINITE);
if (NULL != m_pEmperor)
{
delete m_pEmperor;
m_pEmperor = NULL;
}
ReleaseMutex(m_pMutex);
}
}
void CEmperor::SetEmperorTag( string tag )
{
m_EmperorTag = tag;
}
//Singleton.cpp
#include "stdafx.h"
#include "Emperor.h"
void DoIt()
{
CEmperor *pEmperor1 = CEmperor::GetInstance();
pEmperor1->SetEmperorTag("95");
pEmperor1->EmperorInfo(); CEmperor *pEmperor2 = CEmperor::GetInstance();
pEmperor2->EmperorInfo(); CEmperor *pEmperor3 = CEmperor::GetInstance();
pEmperor3->EmperorInfo(); CEmperor *pEmperor4 = pEmperor3;
pEmperor4->EmperorInfo(); CEmperor *pEmperor5 = NULL;
pEmperor5 = pEmperor4;
pEmperor5->EmperorInfo(); CEmperor::ReleaseInstance();
}
int _tmain(int argc, _TCHAR* argv[])
{
DoIt();
_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF);
_CrtDumpMemoryLeaks();
return 0;
}
单例模式比较简单,但在项目中使用的时候,需要明确只调用CEmperor的GetInstance函数来获取实例。在C#里
有更简单的方法,那就是声明只读的静态变量,比C++简单多了。
但C++更吸引人们去研究,这就是软件研发的乐趣吧。
设计模式C++学习笔记之三(Singleton单例模式)的更多相关文章
- 《Head first设计模式》学习笔记 – 迭代器模式
<Head first设计模式>学习笔记 – 迭代器模式 代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 爆炸性新闻:对象村餐厅和对象村煎饼屋合并了!真是个 ...
- Django 学习笔记之三 数据库输入数据
假设建立了django_blog项目,建立blog的app ,在models.py里面增加了Blog类,同步数据库,并且建立了对应的表.具体的参照Django 学习笔记之二的相关命令. 那么这篇主要介 ...
- 【Visual C++】游戏编程学习笔记之三:游戏循环的使用
本系列文章由@二货梦想家张程 所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44208419 作者:Zee ...
- hive学习笔记之三:内部表和外部表
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- C#设计模式学习笔记:(1)单例模式
本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/8250985.html,记录一下学习过程以备后续查用. 一.引言 设计模式的分类: 1)依目的: 创建型(Cr ...
- 【Java学习笔记之三十】详解Java单例(Singleton)模式
概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...
- 设计模式学习笔记c++版——单例模式
特别注意单例模式c++实现在main.cpp中引用的时候要去申明下: Singleton * Singleton::m_Instance = NULL; //定义性声明 不然会报错:无法解析的外部符号 ...
- 《javascript设计模式》读书笔记四(单例模式)
1.单利模式简单介绍 在<设计模式>中单利模式是一种比較简单的模式,定义例如以下: 确保某一个类仅仅有一个实例,并且自行实例化并向整个系统提供这个实例. 在javascript中则将代码组 ...
- C++ 常用设计模式(学习笔记)
1.工厂模式:简单工厂模式.工厂方法模式.抽象工厂模式 1).简单工厂模式:主要特点是需要在工厂类中做判断,从而创造相应的产品,当增加新产品时,需要修改工厂类. typedef enum { T80 ...
随机推荐
- python第二次周末大作业
题目 ''' HR人力资源管理. 1. 菜单: ("查看员⼯信息","添加员⼯信息", "修改员⼯信息", "删除员⼯信息&quo ...
- java-map复合类型(HashMap-TreeMap)常用操作例子(适合初学者)
package com.net.xinfang.reflect; import java.util.ArrayList; import java.util.HashMap; import java.u ...
- std::rotate使用
1. 进行元素范围上的左旋转 first - 原范围的起始 n_first - 应出现在旋转后范围起始的元素 last - 原范围的结尾 原来:1 2 3 左旋转后(起始元素是2) : 2 3 1
- Css单位px,rem,em,vw,vh的区别
px px就是pixel像素的缩写,相对长度单位,网页设计常用的基本单位.像素px是相对于显示器屏幕分辨率而言的 em em是相对长度单位.相对于当前对象内文本的字体尺寸(参考物是父元素的font-s ...
- Vertica系列:性能优化
Vertica 性能非常好, 平时基本不会碰到性能问题, 即使碰到, 优化也很容易, 而且效果往往会很好. ======================优化工具==================== ...
- springboot(十三):springboot结合mybatis generator逆向工程自动生成代码
错信息generate failed: Exception getting JDBC Driver: com.mysql.jdbc.Driver 上网查了一下,发现原来是generator这个插件在运 ...
- 三十三、Linux 进程与信号——中断系统调用和函数可重入性
33.1 中断系统调用 进程调用 “慢” 系统调用时,如果发生了信号,内核会重启系统调用. 慢系统调用 可能会永久阻塞的系统调用 从终端设备.管道或网络设备上的文件读取 向上述文件写入 某些设备上的文 ...
- GCC编译器原理(三)------编译原理三:编译过程(3)---编译之汇编以及静态链接【2】
4.1.2 符号解析与重定位 (1)重定位 在完成空间和地址的分配步骤之后,链接器就进入了符号解析和重定位的步骤,这是静态链接的核心部分. 先看看 a.o 的反汇编文件: objdump -d a.o ...
- 快速学习 javascript
// js 6种数据类型:字符串.数值.布尔值.undefined.null.object // 三种非数字的数字类型:Infinity -Infinity NaN var str = "H ...
- JavaScript 小工具
1. 字符串格式化输出 支持形如: Orders of {1} or more {0}' {0},{1}代表第几个参数,包含了完善的异常处理.当给定参数少于格式化串中占位符个数时,未找到的直接留白. ...
