C++面试宝典设计模式之单例模式

本文详细介绍了设计模式中的单例模式,包括概念、目的、优缺点、使用场景和实现方式。单例模式确保一个类只有一个实例,常用于设备管理、数据池等场景。文中给出了懒汉式、饿汉式和线程安全的懒汉式单例模式的C++代码示例,强调了根据场景选择合适实现方式的重要性。单例模式的运用能提升代码的可读性和可维护性。
摘要由CSDN通过智能技术生成

C++面试宝典设计模式篇之单例模式


前言

软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。设计模式是面试热门考点,掌握设计模式可以让你深入理解面向对象思想,使设计方案更加灵活,方便后期维护修改。

一、设计模式之单例模式

二、单例模式详细介绍

2.1单例模式概念介绍

单例模式属于创建型模式,这种模式涉及到一种单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一对象的方式。
单例类的特征: 1.单例类最多只能有一个实例;
   2.单例类必须自己创建自己唯一的实例;
   3.单例类必须给所有其他的对象提供这一实例。

2.2使用单例模式的目的和优缺点

目的:使用单例类是为了保证某一个类仅有一个实例,并提供一个访问它的全局访问点。
    单例类主要解决了一个全局使用的类的频繁的创建与销毁。
    所以单例模式有以下几个优点: 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的 创建和销毁实例; 2、避免对资源的多重占用。
    缺点:单例模式有一个不好的地方就是:单例类没有接口,不能继承。

2.3单例模式的使用场景

当我们想在程序中控制实例数目,节约系统资源的时候,就可以考虑使用单例类。
例如:1.频繁创建及销毁的对象,例如工具类;
2.不变的对象;
3.设备管理器,系统中可能有多个设备,但是只有一个设备管理器,用于管理设备驱动;
4.数据池,用来缓存数据的数据结构,需要在一处写,多处读取或者多处写,多处读取;
5.打印机,日志对象;

2.4单例模式的定义方式

定义一个单例类:

(1)私有化构造函数,以防止外界创建单例类的对象。

private Singleton()

不需用拷贝和赋值,在单例模式中,始终只有一个对象

(2)使用类的私有静态指针,变量指向类的唯一实例。(提供一个自身的静态私有成员变量,以指向类的实例;

private static Singleton * uniqueInstance()

(3)使用一个公有的静态方法获取该实例。

public static Singleton * getInstance()

2.5单例模式的实现方式

懒汉式:故名思义,不到万不得已就不会去实例化类,也就是说在第一次用到类实例的时候才会去实例化。与之对应的是饿汉式单例。(注意,懒汉本身是线程不安全的)
饿汉式:饿了肯定要饥不择食。所以在单例类定义的时候就进行实例化。(本身就是线程安全的)
那如何选择懒汉和饿汉模式呢?
特点与选择:

懒汉:直接创建出类的实例化 因为上来就实例化一个对象,占用了内存,并不管主程序是否用到该类。在访问量较小时,采用懒汉实现。这是以时间换空间。

饿汉:由于要进行线程同步,所以在访问量比较大,或者可能访问的线程比较多时,采用饿汉实现,可以实现更好的性能。这是以空间换时间。

三、单例模式代码示例

3.1懒汉式代码示例

/*懒汉式单例模式*/
class Singleton_lazy{
private:
    /*构造函数私有化,保证不在类的外部实例化*/
    Singleton_lazy(){cout<<"我是懒汉式构造函数"<<endl;}
public:
    /*用户接口,在使用的时候创建一个类的实例化*/
    static Singleton_lazy* getInstance(){
        //判断pSingleton是否为NULL,如果为NULL,即判定需要实例化
        if (pSingleton==NULL){
            pSingleton=new Singleton_lazy;
        }
        return pSingleton;
    }
private:
    static Singleton_lazy* pSingleton;    //静态类对象
};
 
//静态对象类外初始化
Singleton_lazy* Singleton_lazy::pSingleton=NULL;

3.2饿汉式代码示例

/*饿汉式单例模式*/
class Singleton_hungry{
private:
    Singleton_hungry(){cout<<"我是饿汉式构造函数"<<endl;}
public:
    /*返回已经创建好的类实例*/
    static Singleton_hungry* getInstance(){
        return pSingleton;
    }
private:
    static Singleton_hungry* pSingleton;
};
 
//类外初始化:直接创建出类的实例 
Singleton_hungry* Singleton_hungry::pSingleton=new Singleton_hungry;

如果想懒汉模式实现线程安全,则应该加锁

3.3线程安全的懒汉式代码示例

#include<iostream>
#include<pthread.h>
#include<unistd.h>
using namespace std;
class Cperson
{
	private:
		Cperson(){}
		~Cperson(){}
	private:
		static Cperson* ps;
		static pthread_mutex_t mutex;
	public:
		static Cperson* GetObject();
		static void Destory(Cperson* p);

};
Cperson* Cperson::ps = 0;  
pthread_mutex_t  Cperson::mutex = PTHREAD_MUTEX_INITIALIZER;

Cperson* Cperson::GetObject() 
{
	if(ps == 0)
	{
		pthread_mutex_lock(&mutex);
		if(ps  == 0)
			ps = new Cperson;
		pthread_mutex_unlock(&mutex);
	}
	return ps;
}

void Cperson::Destory(Cperson* p)
{
	if(p->ps)
	{
		delete p->ps;
		p->ps == NULL;
	}
	pthread_mutex_destroy(&(p->mutex));
}

Cperson* p2;
void* work(void *arg)
{
	p2 = Cperson::GetObject();
	cout<<"work:"<<p2<<endl;
	
}
int main()
{
	pthread_t tid = 0;
	pthread_create(&tid,NULL,work,NULL);
	//Cperson* p2 = Cperson::GetObject();
	Cperson* p1 = Cperson::GetObject();
	sleep(1);//防止主函数执行过快 线程函数还没来得及执行

	cout<<"p1:"<<p1<<endl;
	cout<<"p2:"<<p2<<endl;
	Cperson::Destory(p1);
	return 0;
}

四、总结

设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性以及类的关联关系和组合关系的的充分理解。
正确使用设计模式有很多优点:
1.可以提高程序员的思维能力、编程能力和设计能力。
2.使面试程序设计更加标准化、代码编制更加工程化,使软件开发效率大大提高,从而缩短软件的开发周期。
3.使设计的代码可重用性高、可读性强、可靠性高、灵活性好、可维护性强。
今天博主分享的单例模式只是设计模式的一种,能在适当的场景使用合理的设计模式对于程序员的成长至关重要,后续博主会继续分享设计模式的学习经验。
每日一语:虽然坚持自己的理想很难,但无论最后有没有实现都好,那种执着与信念,将是一生的财富,与大家共勉!

评论 32
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

算法小学徒

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

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

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

打赏作者

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

抵扣说明:

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

余额充值