单例模式设计
本文最后更新于548 天前,其中的信息可能已经过时,如有错误请发送邮件到1739584917@qq.com

什么是单例模式

单例模式是指在整个系统生命周期内,保证一个类只能产生一个实例,确保该类的唯一性。

这么说你可能并不明白,下面我举个例子:

在windows网络编程中,会涉及socket套接字的创建与初始化,并且创建和初始化的过程一般只会执行一次,并且程序执行结束前需要关闭这个套接字。那什么东西可以在程序运行时自动初始化,程序结束时自动析构呢?那就是类。

我们一般会把这个过程封装到一个类里面,把初始化这些过程放到构造函数里面,关闭套接字、释放内存这些过程放到析构函数里,接着创建一个该类的全局变量,就可以实现上述的过程。

如果这个程序只是个人开发,那倒没什么问题,那如果是团队开发,那不能保证这个类的构造与析构只会执行一次,比方说,有人会再声明一个这个类,或者拿已经声明好的类去赋值,这些过程都会触发这个类的构造函数,也就是说会被多次初始化。

所以就需要这个单例模式了,从语法上限制该类的唯一性。

思考

首先我们会想到把构造函数、复制构造函数、析构函数设为私有,但是这样的话,外部也无法访问,彻底与外部隔离了。那我们可以写一个静态成员函数让外界访问。静态成员是一种特殊的成员,类体中的数据成员声明时前面加上关键字 static ,即成为该类的静态数据成员,即静态成员变量。 静态成员变量实际上就是类域中的全局变量,必须初始化,且只能在类体外。 初始化时不受private和protected访问限制。

但这又引出一个新的问题,这个静态成员既然是是全局的,那它就没有this指针,没有this指针就还是无法访问该类的私有成员。

//CServerSocket类的头文件
#pragma once
#include "pch.h"
#include "framework.h"

class CServerSocket
{
public:
	static CServerSocket* getInstance()
	{
		if (m_instance==NULL)//静态函数没有this指针,所有不能直接访问成员变量
		{
			m_instance = new CServerSocket();
		}
		return m_instance;
	}
private:
        static CServerSocket* m_instance;
	CServerSocket()
        {
             //TODO:初始化操作
        }
	CServerSocket& operator=(const CServerSocket&ss){}
	CServerSocket(const CServerSocket&ss){}
	~CServerSocket()
        {
             //TODO:
        }
};

一开始我们在CServerSocket的.cpp文件里是这么写的:

#include "pch.h"
#include "ServerSocket.h"

CServerSocket server;//定义一个CServerSocket的一个类,让这个类去完成构造和析构

但是我们说了,它是不能做成全局的,因为不能够进行初始化。

所以我们改成这样:

#include "pch.h"
#include "ServerSocket.h"

//CServerSocket server;
CServerSocket* CServerSocket::m_instance = NULL; 
CServerSocket* pserver = CServerSocket::getInstance();

做一个全局的指针去接收这个实例,这是可以的。

这样的话你会发现,它没有触发类的析构函数,这也是不行的。你仔细想想,m_instance 这个实例是怎么来的,其实是通过new来的,那有new就应该有delete,如果没有delete,这个类就不会销毁,也就不会调用析构函数。

完善

//CServerSocket类的头文件
#pragma once
#include "pch.h"
#include "framework.h"

class CServerSocket
{
public:
	static CServerSocket* getInstance()
	{
		if (m_instance==NULL)//静态函数没有this指针,所有不能直接访问成员变量
		{
			m_instance = new CServerSocket();
		}
		return m_instance;
	}
private:
        static CServerSocket* m_instance;

        static CHelper m_helper;
	CServerSocket()
        {
             //TODO:初始化操作
        }
	CServerSocket& operator=(const CServerSocket&ss){}
	CServerSocket(const CServerSocket&ss){}
	~CServerSocket()
        {
             //TODO:
        }
        static void releaseInstance()//释放对象
	{
		if (m_instance!=NULL)
		{
			CServerSocket* tmp = m_instance;
			m_instance = NULL;
			delete tmp;
		}
	}
        class CHelper
	    {
	    public:
		CHelper()
		{
			CServerSocket::getInstance();
		}
		~CHelper()
		{
			CServerSocket::releaseInstance();
		}
	};
};
//CServerSocket类的.cpp文件
#include "pch.h"
#include "ServerSocket.h"

//CServerSocket server;
CServerSocket* CServerSocket::m_instance = NULL; 
CServerSocket::CHelper CServerSocket::m_helper;//对象的实现
CServerSocket* pserver = CServerSocket::getInstance();

我们通过在CServerSocket类下再重新定义一个类CHelper,这个类只用于初始化时调用getInstance()初始化m_instance实例对象,而析构函数也只用于调用releaseInstance()来释放实例对象,而CHelper是在全局实现的,保证了这个类也是唯一的,并且main函数前会调用构造函数,main函数结束后会调用析构函数,分别去初始化、释放m_instance这个实例对象。

如果觉得本文对您有所帮助,可以支持下博主,一分也是缘
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇