C++设计模式之单例模式(1)

单例模式的典型优缺点评价:饿汉,懒汉与多线程安全

单例模式的应用案例:缓存

应用

在读取Config的时候,可能需要一些参数进行获取值,比如

Data:www.xxx.com

Option:1

host:http://

其中,data与option是固定的,如果每次取出config.ini里面的内容都需要new一个AppConfig对象,此时内存消耗会变大、所以单例模式中就可以定义一个全局且唯一的一个对象进行读取config

单例模式特点

1 构造函数是私有的

2 有一个全局静态的类属性

3 只允许在类的内部进行构造这个类

4 不依赖new实例化调用类的getInstance方法进行类内部构造

5 线程安全问题

单例模式线程安全问题

懒汉模式

Static Void * getInstance()

{

         If(m_singleton == NULL)

                   m_singleton = mew this;

Return m_singleton;

}

当两条线程同时执行到m_singleton == NULL下面这行代码,由于另外一条线程的推进,使得m_singleton = mew this,而另外一条线程也会跟着m_singleton = mew this进行实例化类,就会出现两个对象,所以在异步当中时间片段被打乱就很容易出现多线程时造成内存泄露问题!


#include <iostream>
#include <sstream>
#include "afxwin.h"
using namespace std;
CRITICAL_SECTION g_cs;
class SingletonMode {
private:
	SingletonMode()
	{
		m_singleton = nullptr;
		cout << "构造一个SingletonMode类" << endl;
	}
public:
	static SingletonMode* getInstance()
	{	//不能在此存放进入许可区、否则出异常
		if (m_singleton == nullptr)
		{
			::EnterCriticalSection(&g_cs);
			if (m_singleton == nullptr)
			{
				m_singleton = new SingletonMode;
			}
			::LeaveCriticalSection(&g_cs);
		}
		return m_singleton;
	}
private:
	static SingletonMode* m_singleton;
};
SingletonMode* SingletonMode::m_singleton = nullptr;	//懒汉模式,如果不为nullptr则为饿汉模式
UINT Func(LPVOID)
{
	cout << hex << SingletonMode::getInstance() << endl;
	return 0;
}
int main(void)
{
	//auto p1 = SingletonMode::getInstance();
	//auto p2 = SingletonMode::getInstance();
	InitializeCriticalSection(&g_cs);
	for (int i = 0; i < 50; i++)
	{
		AfxBeginThread(Func, nullptr);
	}
	DeleteCriticalSection(&g_cs);
	system("pause");
	return 0;
}

普通项目中使用MFC

1 在配置属性,常规选项中MFC的使用,选择MFC在共享DLL中或者是静态库中使用MFC

2 引入 include<afxwin.h>

3 使用AfxBeginThread函数即可创建线程,例如上AfxBeginThread创建50条线程

修正线程安全问题

1 使用临界区进行修正

2 定义临界区

定义结构体CRITICAL_SECTION g_cs;

初始化许可区:::InitializeCriticalSection(&g_cs)

进入许可区:::EnterCriticalSection(&g_cs)

退出许可区:::LeaveCriticalSection(&g_cs)

删除许可区:::DeleteCriticalSection(&g_cs)

3 对getInstance进行加入临界区,从而保证在异步的过程中产生全局且唯一的类

懒汉与饿汉的区别

SingletonMode* SingletonMode::m_singleton = new SingletonMode;

饿汉模式

在单例模式中,存着一个保存当前这个类的指针的静态变量

如果这个静态变量,在初始化的时候就已经被实例化对象了、此时多线程安全也就随之解决了

SingletonMode* SingletonMode::m_singleton = nullptr;

懒汉模式

如果这个静态变量,在初始化的时候是NULL模式、懒汉模式也称为延迟加载、非常常见的策略、在一个非常庞大的类时,在程序没有一定的需求创建这个类时,可以使用懒汉模式进行延迟创建,有助于资源的合理使用(这个过程存在线程安全)

字符串输出方式(一些其他类的使用)

         ostringstream类实现(ostringstreamC++的一个字符集操作模板类,定义在sstream头文件中。ostringstream类通常用于执行C风格的串流的输出操作,格式化字符串,避免申请大量的缓冲区,替代sprintf。推荐)

    string sout;

    ostringstream s;

    s << "p1=" << hex << p1 << ",p2=" << hex << p2;

    sout = s.str();

    cout << sout << endl;

使用CString方式,使用_T宏进行自动转换编码,输出的时候使用wcoutendl

    CString s;

    s.Format(_T("p1=%p,p2=%p"), p1, p2);



    wcout << s.GetString() << endl;

类型易语言使用封装方式输出十六进制

CString dec2hex(int n)

{

    CString s;

    s.Format(_T("%08X"), n);

    return s;



}

    CString s;

    s = "p1=" + dec2hex((int)p1) + ",p2=" + dec2hex((int)p2);

    wcout << s.GetString() << endl;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个卖卡的小男孩~小曾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值