webserver服务器从零搭建到上线(五)|noncopyable类和Logger类

文章目录

  • noncopyable类
    • delete掉了拷贝构造和析构
    • protected成员
      • 1. 允许派生
      • 2.防止直接实例化
    • 主要使用场景
  • Logger类
    • 定义日志级别
    • 输出一个日志类
    • 实现对应的成员函数
    • 实现宏函数来调用日志类
  • 知识拓展

noncopyable类

我们首先进入/muduo/net中查看TcpServer.h、EventLoop.h等等核心代码的类,都继承子一个基类noncopyable,那么我们不得不去看一下noncopyable到底是啥了

class noncopyable
{public:noncopyable(const noncopyable&) = delete;void operator=(const noncopyable&) = delete;protected:noncopyable() = default;~noncopyable() = default;
};

这个类他把它的拷贝构造函数和拷贝复制运算符都delete掉了;另外他写了一个默认default的构造函数和析构函数,相当于就是给直接套了一个空的大括号,因为这两个函数编译器本来就可以自动生成。

delete掉了拷贝构造和析构

我们在使用该基类的时候,去对TcpServer的对象进行拷贝构造和赋值的时候,由于派生类的拷贝和赋值要先去调用基类的拷贝和赋值,然后才是派生类特有部分的拷贝和赋值。

但是由于基类的拷贝和赋值都被delete掉了,所以它的好处就在于我们的其他类如果不想让他被拷贝或者复制,就不用额外写这段代码了,这是一个大型程序所必须的

总结

  • 防止派生类的拷贝构造

protected成员

1. 允许派生

protected 访问修饰符使得只有 noncopyable 类及其派生类能够访问这些构造和析构函数。这意味着不能直接在 noncopyable 类的外部创建该类的实例(即不能直接实例化 noncopyable),但您可以创建派生自 noncopyable 的类的实例。

2.防止直接实例化

如果构造函数和析构函数是 public 的,那么理论上可以直接创建和销毁 noncopyable 类的对象,这违背了类的设计初衷(作为一个基类来阻止复制)。通过将构造和析构函数设为 protectednoncopyable 类的实例化只能通过其子类进行,而 noncopyable 本身不能被直接实例化

主要使用场景

有一个管理资源的类,且这些资源不应该被复制时(比如说,单例模式、文件处理类、数据库连接管理类),您可以让这个类继承自 noncopyable,从而禁止编译时对这些资源进行复制操作

Logger类

日志对于一个软件来说是非常重要的,如果软件上线,用gdb调试有很多不便,所以我们应该使用日志来记录问题。

定义日志级别

定义日志级别一般都是使用枚举类。

enum LogLevel {INFO,ERROR,FATAL,DEBUG,
};

输出一个日志类

日志类应该输出单例模式:

class Logger: noncopyable {
public://获取日志唯一的实例对象static Logger& instance();//设置日志级别void setLogLevel(int level);//写日志的接口void log(std::string msg);
private:int logLevel_;Logger() { }
}

为什么要使用单例模式呢?

  1. 全局访问点:单例模式确保在整个应用程序中只有一个日志类实例,方便统一管理和访问。
  2. 资源共享:避免多个日志实例导致的资源浪费,特别是文件句柄和网络连接等有限资源。
  3. 一致性:确保日志配置和行为一致,避免不同模块使用不同的日志实例导致的日志风格不一致。

实现对应的成员函数

Logger& Logger::instance() { //获取日志唯一的实例对象static Logger logger;return logger;
}void Logger::setLogLevel(int level) {// 设置日志级别logLevel_ = level;
}void Logger::log(std::string msg) {//写日志的接口  【级别信息】time : xxxswitch (logLevel_){case INFO:std::cout << "[INFO]";break;case ERROR:std::cout << "[ERROR]";break;case FATAL:std::cout << "[FATAL]";break;case DEBUG:std::cout << "[DEBUG]";break;default:break;}//打印时间和msgstd::cout << Timestamp::now().toString() << ": " << msg << std::endl;
}

这里的Timestamp类在「webserver服务器从零搭建到上线(六)」会进行介绍。

实现宏函数来调用日志类

用的时候我们不需要让用户来操作这些复杂的步骤:

  • 获取日志实例
  • 设置日志级别
  • 在写日志

我们难道还让用户调用这么多接口吗?
用户真正关心的就是写日志,打印出来,所以我们应该把这些内容全部包装到宏函数里面。

这里定义四种宏,对应4个日志级别

//LOG_INFO("%s %d", arg1, arg2)
//参数 ... 表示可变参
#define LOG_INFO(logmsgFormat, ...) \do { \Logger &logger = Logger::instance(); \logger.setLogLevel(INFO); \char buf[1024] = { 0 }; \snprintf(buf, 1024, logmsgFormat, ##__VA_ARGS__); \logger.log(buf); \} while(0)

在宏定义中,##__VA_ARGS__是一种预处理器语法,用于处理可变参数宏。


#define LOG_ERROR(logmsgFormat, ...) \do { \Logger &logger = Logger::instance(); \logger.setLogLevel(ERROR); \char buf[1024] = { 0 }; \snprintf(buf, 1024, logmsgFormat, ##__VA_ARGS__); \logger.log(buf); \exit(-1); \} while(0)#define LOG_FATAL(logmsgFormat, ...) \do { \Logger &logger = Logger::instance(); \logger.setLogLevel(FATAL); \char buf[1024] = { 0 }; \snprintf(buf, 1024, logmsgFormat, ##__VA_ARGS__); \logger.log(buf); \} while(0)

在ERROR级别应该直接停止程序运行。

最后我们重点谈一下 LOG_DEBUG

#ifdef MUDEBUG
#define LOG_DEBUG(logmsgFormat, ...) \do { \Logger &logger = Logger::instance(); \logger.setLogLevel(DEBUG); \char buf[1024] = { 0 }; \snprintf(buf, 1024, logmsgFormat, ##__VA_ARGS__); \logger.log(buf); \} while(0)
#else#define LOG_DEBUG(logmsgFormat, ...)
#endif

其中的 #ifdef 可以保证我们在release版本中,不定义宏 MUDEBUG,就可以不打印调试信息,毕竟日志属于IO操作,对想能影响较大。

知识拓展

在实现宏函数来调用日志类中我们使用了 snprintf ,它是 C 标准库中的一个函数,用于将格式化输出写入字符串,限制写入的最大字符数以避免缓冲区溢出。它是 sprintf 的安全版本。

int snprintf(char *str, size_t size, const char *format, ...);

参数:
str:指向目标缓冲区的指针。
size:要写入的最大字符数,包括终止空字符。
format:格式字符串,类似于 printf 的格式说明。
…:可变参数,根据格式字符串进行格式化。

使用日志类是通过使用宏函数:

LOG_INFO("func=%s => fd total count:%lu \n", __FUNCTION__, channels_.size());

其中的__FUNCTION__表示当前函数的名称。这个宏是由编译器提供的,帮助开发者在调试和记录日志时自动插入当前函数的名称,便于追踪和排查问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/17093.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

可以免费测试的身份证实名认证接口-C#调用示例

在数字时代的浪潮中&#xff0c;每秒都在上演着信息的急速交互。但在这份高效背后&#xff0c;如何确保每一次交易、登录的安全与真实性&#xff0c;成为了困扰线上平台的一大难题。翔云身份证实名认证接口的出现&#xff0c;正是您稳固防线&#xff0c;提升用户体验的得力助手…

信号量和事件及队列补充

【一】信号量(了解&#xff09; 信号量Semahpore&#xff08;同线程一样&#xff09; 【1】引入 互斥锁 同时只允许一个线程更改数据&#xff0c;而Semaphore是同时允许一定数量的线程更改数据 【2】例子 比如厕所有3个坑&#xff0c;那最多只允许3个人上厕所&#xff0c;后…

死锁和递归锁

【一】死锁 【1】介绍 死锁是指两个或多个进程&#xff0c;在执行过程中&#xff0c;因争夺资源而造成了互相等待的现象 即两个或多个进程持有各自的锁并视图获取对方持有的锁&#xff0c;从而导致阻塞&#xff0c;不能继续执行&#xff0c;一直僵在这 这种情况下&#xff0…

LeetCode - 贪心算法 (Greedy Algorithm) 集合 [分配问题、区间问题]

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/139242199 贪心算法&#xff0c;是在每一步选择中&#xff0c;都采取当前状态下&#xff0c;最好或最优&#xff08;即最有利&#xff09;的选择&…

Linux相关知识

一.Linux是什么? 1.Linux是一款开源免费的操作系统 目前市面上较知名的发行版有:Ubuntu,ReaHat,Centos,Debain… ​ 2.Linux的优势? ​ ①性能强劲,安全稳定 ​ ②可定制 ​ ③硬件配置要求低 ​ ④嵌入移动设备 二.Linux安装 三.文件和目录结构 /bin 常用命令 /sbin root…

奇门遁甲古籍《烟奇要览》

《烟奇要览》 全书共178页 时间有限&#xff0c;仅上传部分图片&#xff01;

YOLOv10介绍与推理--图片和视频演示(附源码)

导 读 本文主要对YOLOv10做简单介绍并给出推理图片和视频的步骤演示。 YOLOv10简介 YOLOv10是清华大学的研究人员在Ultralytics Python包的基础上&#xff0c;引入了一种新的实时目标检测方法&#xff0c;解决了YOLO 以前版本在后处理和模型架构方面的不足。通过消除非最大抑…

人工智能超万卡集群的核心设计原则和架构

超万卡集群的核心设计原则和架构 超万卡集群建设方兴未艾,当前主要依托英伟达GPU及其设备。英伟达GPU在大模型训练中表现卓越,但国产AI芯片虽进步显著,性能与生态构建仍存差距。面对诸多挑战,构建技术领先、基于国产生态的超万卡集群,仍需不断突破与创新。 大模型升级至万…

Linux终端连接工具

终端连接工具有很多中&#xff0c;这里我只收集了一些常用的或免费的工具 我一般会配套使用&#xff1a; FinalShell -->命令行工具&#xff08;Mac和win&#xff09; WinSCP -->文件上传工具&#xff08;win&#xff09; filezilla -->文件上传工具&#xff08;Mac …

TensorBoard相关学习

TensorBoard是Google为TensorFlow框架开发的一个强大的可视化工具&#xff0c;它可以帮助用户更直观地理解、分析和调试机器学习模型的训练过程。通过TensorBoard&#xff0c;你可以可视化模型的结构、监控训练过程中的指标变化&#xff08;如损失函数、准确率&#xff09;、查…

金锋关晓柔短视频:成都鼎茂宏升文化传媒公司

金锋关晓柔短视频&#xff1a;情感与创意的交织 在短视频的浪潮中&#xff0c;无数创作者凭借独特的视角和创意脱颖而出。其中&#xff0c;金锋和关晓柔共同打造的短视频系列以其深厚的情感内涵和精湛的创意表达&#xff0c;成都鼎茂宏升文化传媒公司吸引了大量观众的关注&…

Unity Hub 添加模块报错 Validation Failed 的解决办法

提供两种方法&#xff0c;请自行选择其中一种。 在C:\Windows\System32\drivers\etc\hosts中添加下面的内容并保存后&#xff0c;完全关闭Unity Hub并重新打开&#xff0c;再次尝试下载刚刚失败的模块。 127.0.0.1 public-cdn.cloud.unity3d.com 127.0.0.1 public-cdn.cloud.…

知识融合概述

文章目录 知识融合知识融合过程研究现状技术发展趋势 知识融合 知识融合的概念最早出现在1983年发表的文献中&#xff0c;并在20世纪九十年代得到研究者的广泛关注。而另一种知识融合的定义是指对来自多源的不同概念、上下文和不同表达等信息进行融合的过程认为知识融合的目标是…

vue数据持久化仓库

本文章是一篇记录实用性vue数据持久化仓的使用&#xff01; 首先在src中创建store文件夹&#xff0c;并创建一个根据本页面相关的名称&#xff0c; 在终端导入&#xff1a;npm i pinia 和 npm i pinia-plugin-persistedstate 接下来引入代码&#xff1a; import { defineSt…

大众点评全国店铺基础信息采集2024年5月美食、丽人、休闲娱乐、酒店、结婚、爱车、宠物、亲子、医疗、运动等上千万家

大众点评全国店铺基础信息采集2024年5月美食、丽人、休闲娱乐、酒店、结婚、爱车、宠物、亲子、医疗、运动等上千万家 点位示例&#xff1a; 店铺id l4QWAe0vWddska61 店铺名称 太平洋影城(春熙店) 十分制服务评分 8.3 十分制环境评分 8.3 十分制划算评分 8.1 人均价格 …

Python Anaconda环境复制

虚拟环境复制 conda-pack 第一种方式 conda打包 在打包之前如果没有conda-pack包的话&#xff0c;需要安装pip install conda-pack打包 conda pack -n py36 -o py366.tar.gz -o就是给导出得到的压缩包就在当前目录下 传输到另外一台服务器上 有两台linux服务器&#xff0c…

有哪些永久免费的进销存管理软件?

我明白许多中小企业在寻求进销存系统时&#xff0c;希望能找到一款完全免费的解决方案&#xff0c;以减轻经济压力。这种心态非常正常&#xff0c;毕竟成本是任何企业都需要仔细考虑的因素。然而&#xff0c;我要强调的是&#xff0c;市场上那些声称“完全免费”的进销存系统&a…

东子哥:从来不拼搏的人,不是我的兄弟!新一轮裁员潮即将来临!

今年初&#xff0c;包括微软、亚马逊、谷歌母公司Alphabet等在内的巨头先后宣布裁员计划&#xff0c;曾掀起了一轮裁员潮。 进入年中阶段&#xff0c;特斯拉、理想汽车、TikTok、安德玛等知名巨头&#xff0c;也先后宣布裁员计划&#xff0c;难道&#xff0c;新一轮裁员潮已经…

OrangePi AIpro评测 - 基础操作篇

0. 环境 ●OrangePi AIpro ●win10笔记本 ●路由器 准备下win10电脑、路由器&#xff0c;这些板卡通常是在网络正常的环境下才方便测试。 还要准备OrangePi AIpro的官方资料&#xff1a; http://www.orangepi.cn/html/hardWare/computerAndMicrocontrollers/service-and-suppo…

第八届能源、环境与材料科学国际学术会议(EEMS 2024)

文章目录 一、重要信息二、大会简介三、委员会四、征稿主题五、论文出版六、会议议程七、出版信息八、征稿编辑 一、重要信息 会议官网&#xff1a;http://ic-eems.com主办方&#xff1a;常州大学大会时间&#xff1a;2024年06月7-9日大会地点&#xff1a;新加坡 Holiday Inn …