C++单例模式实现Log系统

 使用智能指针实现对单例模式指针内存的管理,并采用模板编程做到一句宏定义就能调用方法

#ifndef _SINGLETON_H_
#define _SINGLETON_H_
#pragma once
#include <memory>
template <typename T>
class CSingleton
{
public:
	static std::unique_ptr<T>& GetInstance()
	{
		if (!m_pInstance)
			m_pInstance.reset(new T);
		return m_pInstance;
	}

private:
	CSingleton() {}
	~CSingleton() {}

	static std::unique_ptr<T> m_pInstance;
};
template <typename T>
std::unique_ptr<T> CSingleton<T>::m_pInstance(nullptr);
#endif	//_SINGLETON_H_

拿LOG系统做示范 

Log.h

#ifndef _LOG_H_
#define _LOG_H_
#pragma once
#include <string>
#include "Singleton.h"
#include "EnumDef.h"
class CLog
{
	CLog(const CLog&)				   = delete;
	const CLog& operator=(const CLog&) = delete;

public:
	bool Init();
	void Fini();
	CLog();
	~CLog();
	void WriteLog(LOG_LEV eType, const char* file, const char* func, int line, const char* pszFormat, ...);

private:
	char		m_szPath[256];
	std::string m_strLev;
};
#define FILENAME(x) strrchr(x, '\\') ? strrchr(x, '\\') + 1 : x

#define LOG (*CSingleton<CLog>::GetInstance())

#define LOGDEBUG(format, ...) LOG.WriteLog(LOG_LEV_DEBUG, FILENAME(__FILE__), __FUNCTION__, __LINE__, format, ##__VA_ARGS__)

#define LOGINFO(format, ...) LOG.WriteLog(LOG_LEV_INFO, FILENAME(__FILE__), __FUNCTION__, __LINE__, format, ##__VA_ARGS__)

#define LOGWARN(format, ...) LOG.WriteLog(LOG_LEV_WARN, FILENAME(__FILE__), __FUNCTION__, __LINE__, format, ##__VA_ARGS__)

#define LOGERROR(format, ...) LOG.WriteLog(LOG_LEV_ERROR, FILENAME(__FILE__), __FUNCTION__, __LINE__, format, ##__VA_ARGS__)
#endif	//_LOG_H_

Log.cpp

#include "Log.h"
#include <direct.h>
#include <io.h>
#include <time.h>
#include <stdarg.h>
#include <assert.h>
using namespace std;
bool CLog::Init()
{
	if (!_getcwd(m_szPath, 256))
		return false;
	//设置log目录
	strcat_s(m_szPath, "\\..\\log\\");
	if (_access(m_szPath, 6))
	{
		if (_mkdir(m_szPath) == -1)
		{
			return false;
		}
	}
	return true;
}

void CLog::Fini() {}
CLog::CLog()
{
	memset(m_szPath, 0, 256);
}

CLog::~CLog() {}

void CLog::WriteLog(LOG_LEV eType, const char* file, const char* func, int line, const char* pszFormat, ...)
{
	//获取时间
	tm	   t;	 // tm结构指针
	time_t now;	 //声明time_t类型变量
	time(&now);	 //获取系统日期和时间
	localtime_s(&t, &now);
	//创建日志文件
	FILE* fp;
	char  LogName[255];
	//按照日志类型创建不同日志文件
	switch (eType)
	{
	case LOG_LEV_ERROR:
		m_strLev = "err";
		break;
	case LOG_LEV_DEBUG:
		m_strLev = "debug";
		break;
	case LOG_LEV_INFO:
		m_strLev = "info";
		break;
	case LOG_LEV_WARN:
		m_strLev = "warn";
		break;
	default:
		break;
	}
	snprintf(LogName, 255, "%s%s%d-%d-%d.log", m_szPath, m_strLev.c_str(), t.tm_year + 1900, t.tm_mon + 1, t.tm_mday);
	fopen_s(&fp, LogName, "a+");
	assert(fp);

	char szContent[512];
	//日志内容格式化
	const char* formatHead = "%d-%d-%d\t%02d:%02d:%02d\t%s\t%s\t%d\t";
	int			n		   = snprintf(szContent, 256, formatHead, t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, file, func, line);
	//写入内容,并换行
	va_list valist;
	va_start(valist, pszFormat);
	vsnprintf(szContent + n, 256, pszFormat, valist);

	fputs(szContent, fp);
	fprintf(fp, "\n");
	va_end(valist);
}

使用示范

	LOG.Init();
	//启动WinSock2环境
	WSADATA wsaData;
	if (!WSAStartup(MAKEWORD(2, 2), &wsaData))
	{
		LOGERROR("WSAStartup Err");
		return 0;
	}

这边没有调用LOG.Fini(),原因是Log系统中没有需要释放的资源,故不写

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值