【C++基础之九】单例模式

21 篇文章 49 订阅

1.作用

单例模式目的就是为了保证一个类只有一个实例。


2.原理

(1)私有静态指针变量实现:使用类的私有静态指针变量指向类的唯一实例,并用一个公有的静态方法获取该实例。

(2)静态局部变量实现:在公有静方法中定义指向该类的一个静态局部变量,并返回该静态局部变量。


3.实现

3.1.私有静态指针变量实现

3.1.1.特点

A.它有唯一一个私有的、指向类的的静态成员指针m_pInstance。

B.它有一个公有的暴露该单例的静态方法getInstance。

C.构造函数是私有的,避免从其他地方创建该类实例。

D.定义单例类中私有内嵌类CGarbo,在其析构函数中释放单例指针。

E.定义CGarbo类的一个实例作为静态成员变量,利用程序结束系统会自动析构所有全局变量的特性来自动释放单例指针。

3.1.2.示例

//Singleton1.h
#pragma once

class CSingleton1
{
public:

	static CSingleton1* getInstance()
	{
		if ( m_pInstance == NULL )
			m_pInstance = new CSingleton1();
		return m_pInstance;
	}

private:

	CSingleton1();

	static CSingleton1* m_pInstance;

	class CGarbo//唯一的作用就是在析构时删除m_pInstance
	{
	public:
		~CGarbo()
		{
			if (CSingleton1::m_pInstance!=NULL)
			{
				delete CSingleton1::m_pInstance;
			}
		}
	};

	static CGarbo m_garbo;//程序结束,系统会自动调用其析构函数

};
//Singleton1.cpp
#include "StdAfx.h"
#include "Singleton1.h"

CSingleton1* CSingleton1::m_pInstance=NULL;//静态成员变量的定义
CSingleton1::CGarbo CSingleton1::m_garbo;//内嵌类静态成员变量的定义

CSingleton1::CSingleton1()
{

}
3.1.3.内存泄漏检测

通过vld进行检测内存泄漏,当未添加CGarbo类,内存泄漏一个字节,即该空单例类实例所占的1个字节,如下。添加CGarbo类及静态成员变量后,内存无泄漏。

Visual Leak Detector Version 2.3 installed.
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 1 at 0x003AC038: 1 bytes ----------
  Call Stack:
    d:\microsoft visual studio 9.0\projects\testcpp\testsingleton\singleton1.h (11): TestSingleton.exe!CSingleton1::getInstance + 0x7 bytes
    d:\microsoft visual studio 9.0\projects\testcpp\testsingleton\testsingleton.cpp (12): TestSingleton.exe!wmain
    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (583): TestSingleton.exe!__tmainCRTStartup + 0x19 bytes
    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (403): TestSingleton.exe!wmainCRTStartup
    0x7C81776F (File and line number not available): kernel32.dll!RegisterWaitForInputIdle + 0x49 bytes
  Data:
    CD  

3.2.静态局部变量实现

3.2.1.特点

A.无需考虑内存释放问题。

B.禁用类拷贝和类赋值。

3.2.2.示例

//Singleton2.h
#pragma once

class CSingleton2
{
public:

	static CSingleton2& getInstance()
	{
		static CSingleton2 instance;
		return instance;
	}

private:

	CSingleton2();
	CSingleton2(const CSingleton2 &);
	CSingleton2 & operator = (const CSingleton2 &); 

};
3.2.3.无内存泄漏相关问题


  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C++ 中实现线程安全的单例模式可以使用以下方法: 1. 懒汉式,加锁:使用 `std::mutex` 来实现线程安全,确保在多线程环境下只创建一个实例。在 getInstance() 方法中使用 `std::lock_guard` 来对互斥锁进行自动加锁和解锁。 ```cpp #include <mutex> class Singleton { private: static Singleton* instance; static std::mutex mtx; Singleton() {} public: static Singleton* getInstance() { std::lock_guard<std::mutex> lock(mtx); if (instance == nullptr) { instance = new Singleton(); } return instance; } }; Singleton* Singleton::instance = nullptr; std::mutex Singleton::mtx; ``` 2. 双重检查锁定:在懒汉式的基础上进行改进,减少锁的使用次数,提高性能。在 getInstance() 方法内部加入双重检查,第一次检查不加锁,只有在实例为 nullptr 时才加锁创建实例。 ```cpp #include <mutex> class Singleton { private: static Singleton* instance; static std::mutex mtx; Singleton() {} public: static Singleton* getInstance() { if (instance == nullptr) { std::lock_guard<std::mutex> lock(mtx); if (instance == nullptr) { instance = new Singleton(); } } return instance; } }; Singleton* Singleton::instance = nullptr; std::mutex Singleton::mtx; ``` 这些方式都可以实现线程安全的单例模式,具体选择哪种方式取决于具体的场景和需求。需要注意的是,在多线程环境下,使用静态变量来保存实例时,需要保证其线程安全性,可以使用互斥锁 (`std::mutex`) 或其他线程同步机制来实现。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值