单例模式

本文详细探讨了单例模式的设计思想,包括如何通过使构造函数和析构函数私有化、使用静态方法getInstance来确保对象的唯一性。同时,对比了单例模式与全局变量的不同,指出全局变量可能会产生多个实例,而单例模式采用懒汉式加载,只有在需要时才创建对象,并且允许继承。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单例模式

要求:单例模式中,只能存在一份对象。

思路:如果创建的是栈对象,则无论如何都不可能做到只有一份对象,因为可以创建一个就可以创建无限多个。所以只有从堆对象入手。

要点1 既然要阻止栈对象的创建,就要搞残构造函数和析构函数。把构造函数和析构函数变为私有即可。

要点2 构造和析构函数都变私有了,所以堆对象的创建也凉了。

要点3 不论创建栈对象还是堆对象,只要创建对象,就免不了对构造函数的调用,既然在类外没有用武之地了,可以在类内调用呀!(注意:栈对象的创建需要构造函数和析构函数都为公有,堆对象只需构造函数为公有即可

要点4 由此,我们在类内定义一个getInstance方法,用来创建一个对象,但是先有鸡还是先有蛋的问题又一次摆在眼前,类内的方法在类外需要用实例来调用,所以此刻聚光灯应该给到static,它能解决这个问题。用static修饰的getInstance方法可以直接用类名调用。

要点5 之前的问题又来了,还是可以通过getInstance方法创建多个对象,问题不大,一个if判断就可以搞定。只在第一次调用getInstance方法是的时候才new出对象,此后都直接返回该对象地址!

要点6 但用什么类型去接这个地址呢?由于getInstance方法是static的,所以该方法内部的变量也只能是static类型。即定义一个私有成员_pInstance为static类型。并在类外初始化为NULL。

#include <iostream>
using std::cout;
using std::endl;

//单例模式:
//要求:在内存中只能创建一个对象
//1. 该对象不能栈(全局)对象
//2. 该对象只能放在堆中
//
//应用场景:
//1. 直接替换任意的全局对象(变量)
//2. 配置文件 
//3. 词典类

#include <stdio.h>

class Singleton
{
public:
	static Singleton * getInstance()
	{
		if(NULL == _pInstance) {
			_pInstance = new Singleton();//在类内部掉用构造函数
		}
		return _pInstance;
	}

	static void destroy()
	{
		if(_pInstance) {
			delete _pInstance;
		}
	}

	void print()
	{
		cout << "Singleton::print()" << endl;
	}
private:
	Singleton() {	cout << "Singleton()" << endl; }
	~Singleton() {	cout << "~Singleton()" << endl;	}
private:
	static Singleton * _pInstance; //数据成员
};

Singleton * Singleton::_pInstance = NULL;

//Singleton s3;
//static Singleton s4;
 
int main(void)
{
	//Singleton s1;//error 栈对象, 必须让该语句无法编译通过
	//Singleton s2;
	//Singleton * p1 = new Singleton();//必须让该语句无法编译通过
	//Singleton * p2 = new Singleton();
#if 1
	Singleton * p1 = Singleton::getInstance();
	Singleton * p2 = Singleton::getInstance();
#endif
	printf("p1 = %p\n", p1);
	printf("p2 = %p\n", p2);

	Singleton::getInstance()->print();

	//delete p1;//error, 希望该语句编译无法通过(是为了同样用static的方法进行销毁)

	Singleton::destroy();

	return 0;
}

全局变量与单例模式辨析

不同点:全局变量实际可以有多个实例,且全局变量用到与否都已经在stack上创建,单例模式是懒汉模式,用到时才创建。且单例模式可以被继承。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值