C++单例

基本步骤

1、构造、析构函数设置为私有

2、operator=和拷贝也设置为私有

private:
	CSocket& operator=(const CSocket& cs) {
		...
	}
	CSocket(const CSocket& cs) {
	    ...
	}
	CSocket() {
		...
	}
	~CSocket() {
		...
	}

3、写一个公有的 静态 类指针 函数static 类* getInstance(){},类外可通过类名::函数名进行访问

public:
	static CSocket* getInstance() {
		if (m_instance == NULL) {
			m_instance = new CSocket();
		}
		return m_instance;
	}

4、声明一个私有的 静态 类指针实例 类* m_instance(PS:静态函数没有this指针,无法直接访问成员变量)

private:
	static CSocket* m_instance;

5、4中的静态 类指针实例仅仅为声明,没有实现,类似extern,在外部(类.cpp)写实现,类* 类::m_instance = NULL;

CSocket* CSocket::m_instance = NULL;

6、外部写一个类指针pserver=类::getInstance(); 即pserver=4中的实例

CSocket* pserver = CSocket::getInstance();

7、类中写一个辅助类CHelper,用来调用类的析构(已私有)函数

private:
	static void releaseInstance() {
		if (m_instance != NULL) {
			CSocket* tmp = m_instance;
			m_instance = NULL;
			delete tmp;
		}
	}
	class CHelper {
	public:
		CHelper() {
			CSocket::getInstance();
		}
		~CHelper() {
			CSocket::releaseInstance();
		}
	};

private:
	static CHelper m_helper;

8、类外初始化m_helper

CSocket::CHelper CSocket::m_helper;

完整代码示例

''''Socket.h''''
#pragma once
#include <WinSock2.h>
#include<iostream>

class CSocket
{
private:
	SOCKET m_sock;
	SOCKET m_client;
public:
	static CSocket* getInstance() {
		if (m_instance == NULL) {
			m_instance = new CSocket();
		}
		return m_instance;
	}
	//套接字初始化
	bool InitSocket() {
		if (INVALID_SOCKET == m_sock)
		{
			printf("socket errorNum = %d\n", GetLastError());
			return FALSE;
		}

		SOCKADDR_IN serv_adr;  //定义主机
		serv_adr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);  //支持任意地址
		serv_adr.sin_family = AF_INET;   //协议族是IPV4
		serv_adr.sin_port = htons(6000);   //端口6000

		if (SOCKET_ERROR == bind(m_sock, (SOCKADDR*)&serv_adr, sizeof(SOCKADDR))) {
			printf("bind errorNum = %d\n", GetLastError());
			return FALSE;
		}

		//最大监听数目5
		if (SOCKET_ERROR == listen(m_sock, 5)) { //等待接入的队列的最大长度
			printf("listen errorNum = %d\n", GetLastError());
			return FALSE;
		}

		return TRUE;
	}

	bool AcceptClient() {
		SOCKADDR_IN client_adr;  //定义分机
		int cli_sz = sizeof(client_adr);
		// 主机去处理客户端连接
		m_client = accept(m_sock, (SOCKADDR*)&client_adr, &cli_sz);  //无连接时,需阻塞此处
		if (m_client == -1) return FALSE;
		return TRUE;
	}

	int DealCommand() {
		if (m_client == -1) return FALSE;
		char buffer[1024] = "";
		while (TRUE) {
			int len = recv(m_client, buffer, sizeof(buffer), 0);
			if (len <= 0) {
				return -1;
			}
			//TODO:处理命令
		}
	}

	bool Send(const char* pData, int nSize) {
		if (m_client == -1) return FALSE;
		return send(m_client, pData, nSize, 0) > 0;
	}

private:
	CSocket& operator=(const CSocket& cs) {
		m_sock = cs.m_sock;
		m_client = cs.m_client;
	}
	CSocket(const CSocket& cs) {
		m_sock = cs.m_sock;
		m_client = cs.m_client;
	}
	CSocket() {
		//m_sock = INVALID_SOCKET;
		m_client = INVALID_SOCKET;

		if (InitSockEnv() == false) {
			std::cout << "套接字环境初始化失败\n";
			exit(0); //终止当前运行的程序,并返回一个状态码给操作系统
		}

		m_sock = socket(AF_INET, SOCK_STREAM, 0);   //IPv4
	}
	~CSocket() {
		// 关闭总机
		closesocket(m_sock);
		// 清理网络环境
		WSACleanup();
	}
	//网络环境初始化
	bool InitSockEnv() {
		// 加载套接字库
		WORD wVersionRequested;
		WSADATA wsaData;
		int err;
		wVersionRequested = MAKEWORD(1, 1);
		// 初始化套接字库
		err = WSAStartup(wVersionRequested, &wsaData);
		if (err != 0)
		{
			return false;
		}
		// 检查返回的Winsock版本是否为1.1
		if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
		{
			WSACleanup();  //清理Winsock资源
			return false;
		}
		return true;
	}

private:
	static void releaseInstance() {
		if (m_instance != NULL) {
			CSocket* tmp = m_instance;
			m_instance = NULL;
			delete tmp;
		}
	}
	class CHelper {
	public:
		CHelper() {
			CSocket::getInstance();
		}
		~CHelper() {
			CSocket::releaseInstance();
		}
	};

private:
	static CHelper m_helper;
	static CSocket* m_instance;
};

//extern关键字用于声明一个变量或函数是在别的文件中定义的,
//或者是在程序的全局范围内定义的,而不是在当前的源文件中
extern CSocket server;
''''Socket.cpp''''
#include "Socket.h"
//CSocket server;

CSocket* CSocket::m_instance = NULL;
CSocket::CHelper CSocket::m_helper;
 
CSocket* pserver = CSocket::getInstance();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

yy_xzz

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

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

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

打赏作者

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

抵扣说明:

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

余额充值