P11 如何写一个C++类 Log日志基础

news2024/12/25 14:30:30

01 前言

到目前为止,我们学了类 class,本期我们要尝试着从头开始写一个类。

本期不会讲的太深。我们不会写非常复杂的类,我们要会完成一个基本的 log 类

02 为什么使用 log

首先我们先分析一下我们的需求,这个 log 类到底是什么?具体要完成什么功能?

这个 log 类是我们管理日志信息的一种方式,换句话说我们想要我们的程序打印消息或信息到控制台。这个通常对调试代码非常有帮助。

比如,在游戏或应用中,如果我们想知道发生了什么,你只需将事务的状态打印到控制台,因为应用程序中的控制台就像一个展示信息的地方,我们可以用它来打印出发生了什么。这也是几乎可以保证代码在正确工作的东西。

控制台基本上是内置在操作系统中的东西,所以我们几乎可以保证它不会出问题。

我很喜欢用 log 类作为例子,

  1. 因为日志系统可以根据您的需要从简单的或复杂的都行,——有些日志系统非常复杂,甚至有可能有几千行代码,而这些仅仅是为了把东西打印到控制台。但它们对调试和开发非常重要,所以花点时间在这上面是值得的。
  2. log 日志系统不仅可以做简单将信息打印到控制台这样的事情,也可以用不同颜色打印或是通过网络输出日志消息到一个文件,你可以做很多事情,你最终完成的 log 类十行到一万行代码都行。就是这样。

这就是为什么我会说 log 是一个很好的例子的原因。

03 log 需要包括哪些参数

log 类开始的时候非常简单,它提供向控制台写入文本的能力并保持某种日志级别,也就是我们真正想要发送给控制台的日志信息的级别,开始我们有三个层次

  • 错误 eror
  • 警告 warning
  • 信息 information

我们将来可能我们的日志系统级别设置为警告 warning。这意味着只会打印警告和错误而不会打印跟踪消息。这是非常有用的。如果你不想看到一堆信息,你只想知道哪里出了问题或者你的警告是什么,同样通过过滤实际发送和打印的内容。控制台也会很清爽

我们首先肯定是先实例化一个 log。然后,我们可能指定某种日志级别作为一个实际参数,暂且先跳过它。

log 肯定会设置一个 log 级别, SetLevel 方法的参数 WarnLevel就是指 warning 级别,这意味着只有警告或更重要的信息,比如警告或错误,才会被打印出来。但不跟踪消息。

然后我可能想要打印一个警告信号。

通过以上模拟操作,现在我知道了我的 log 类大概是什么样子了,我们可以直接回去类中开始填空。

这两个函数都是需要能够在外部访问的,所以我们设置它的可见性为 public。

首先是 SetLevel 函数,将 log 级别也就是 level 作为函数的整型参数,这样比较简单。然后这个函数会做一些事情。

然后还有一个 Warnint 函数,它有一个 const char 的参数,是我们的 message。const char 就是字符串的意思,后面我们会专门有一期介绍字符串的内容,现在先知道这些就可以了。

我们现在还有一个问题,这几个函数都已经存在了,可是 lWarningLevel 不存在,让我们开始声明 log 的级别变量。

我们创建一个私有的成员变量来保存我们的 log 级别的设定,它是一个整形,我把它叫做 M_Level,——按照惯例我使用了M_作为前缀,这样可以提示我们这是一个私有的类成员变量,通过这样的方式当我在函数内部写代码时,我就能知道在类代码中哪些是成员变量哪些只是局部变量,当然这样的写法约定不是必须的,但是它确实对整理你的代码并保持代码干净很有帮助。特别是当你处理大型代码库和复杂类这样的东西时。所以我建议大家遵循这样的惯例。

顺便,我们快速地将 SetLevel 函数设置完成。在它里面将参数值赋值给成员变量 M_Level。

让我们回到 main中,处理 LogLevelWarning 这个地方。

我们前面已经规划好了,设为 2 的意思是信息(或者跟踪),1的意思是警告,0的意思是错误,直接这样设置的话,代码读起来有点困难,如果我写的代码是那样的话,读代码的时候会有很多疑问,什么是1?1是个啥?我会不知道它是什么意思,只能靠记忆来记住它代表什么意思,我不想这样处理这个问题。因此我们要创建一些变量,当它的值是某些值的时候表示我们想要表示的东西。

我们在这里将它们设为公共 public 变量,你可以看到我在 log 类中用了两次 public,我喜欢把类中不同的部分分开来写,换句话说,public 方法可能在一个部分,然后 public 变量可以放在另一部分, public 静态变量可能会放在另一块中,这就是我的风格,你可以参考。

这些都是参数,所以我将它设置为 const int ,然后将 LogLevelWarning 设为1,我们还需要为错误写一个日志级别,LogLevelError 设置为零,然后我要为日志的信息跟踪再写一个 LogLevelInfo,让它等于2。

因此我们有三种类型的日志消息,我们有错误 Error、警告 warning、还有信息 information,默认情况下我会把我的日志级别设置为 LogLevelInfo,意思是把所有的东西都应该打印出来。

以上。

最后我们完善一下类里面的方法

我们现在有个问题。

我们当前的代码没有办法做到这个需求:如果日志级别设置成了 warning,就不要打印所有的 Info 消息。

我们可以通过添加 if 语句来搞定这个。

如果日志级别大于或等于这个特定的消息级别,那么就继续,Warn 和 Info方法也是一样的。然后我们将main函数中的 LogLevelWarning 调整为 log.LogLevelWarning。我们已经将 log 设置为警告级别。

04 运行log代码

运行我们的代码,看看具体的效果。我们试试打印 warning信息和 Error信息。

没有问题,就是我们想的那样。

后话

我们实现了所有的目标,创造了一个非常基本的 log 类。

但是我想说这绝对不是我自己写 log 类的方式,因为有一些问题需要解决,一个经验丰富的程序员是不会这样写的,这不是特别完整的代码,但它是比较基础的代码

#include <iostream> 

class Log
{
public:
    const int LogLevelError = 0; //日志级别Error = 0
    const int LogLevelWarning = 1; //
    const int LogLevelInfo = 2; //

private:
    int m_level;  //私有的变量,用于类的内部

public:
    void setLevel(int level)   //设置日志级别
    {
        m_level = level;    //
    }
    void Error (const char* messge)   //打印警告级别的日志信息
    {
        if(m_level >= LogLevelError)
            std::cout << messge << std::endl;
    }

    void warning(const char* messge)   //打印警告级别的日志信息
    {
        if(m_level >= LogLevelWarning)
            std::cout << messge << std::endl;
    }

    void Info(const char* messge)   //打印警告级别的日志信息
    {
        if(m_level >= LogLevelInfo)
            std::cout << messge << std::endl;
    }

};


int main()
{
    Log log;
    log.setLevel(log.LogLevelWarning);   //日志级别设为warning 1
    log.warning("hello ,this is warning");
    log.Error("hello,this is Error"); //
    log.Info("this is Info"); //
    return  0;
}

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

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

相关文章

安捷伦E4404B频谱分析仪,100 Hz 至 6.7 GHz

E4404B是安捷伦ESA-E系列频谱分析仪&#xff0c;它是一款能够适应未来发展需求的中高端频谱分析仪解决方案。该系列在频谱分析仪的测量速度、动态范围、精度和功率分辨能力等方面&#xff0c;都为类似价位的产品树立了性能标杆。其灵活的平台设计使得研发、制造和现场服务工程师…

HCIA-RS基础-距离矢量路由协议

前言&#xff1a; 动态路由协议根据寻径方式可以分为距离矢量路由协议和链路状态路由协议。本文将详细介绍距离矢量路由协议的原理&#xff0c;并阐述其中一个重要概念——路由环路&#xff0c;同时介绍如何避免路由环路的方法。通过学习本文&#xff0c;您将能够深入理解距离矢…

探秘:性能测试中最常见的陷阱与解决方案!

概述一下性能测试流程&#xff1f; 1.分析性能需求。挑选用户使用最频繁的场景来测试。确定性能指标&#xff0c;比如&#xff1a;事务通过率为100%&#xff0c;TOP99%是5秒&#xff0c;最大并发用户为1000人&#xff0c;CPU和内存的使用率在70%以下2.制定性能测试计划&#x…

Acrel-2000电力监控系统在上海大世界保护修缮工程项目中的应用

摘要&#xff1a;安科瑞生产厂家1876150/-6237黄安南 介绍上海大世界电力监控系统&#xff0c;采用智能电力仪表采集配电现场的各种电参量和开关信号。系统采用现场就地组网的方式&#xff0c;组网后通过现场总线通讯并远传至后台&#xff0c;通过Acrel-2000型电力监控系统实现…

CCC联盟——UWB MAC(二)

在上一篇文章中对CCC联盟UWB MAC框架进行了介绍&#xff0c;在本文中&#xff0c;将MAC层的时间网格进行简单介绍。 2、MAC时间网格&#xff08;Time Grid) DK UWB测距协议属于一对多&#xff08;One to Many, O2M)测距协议。发起者&#xff0c;每次发送4帧&#xff0c;接收N帧…

浅谈如何成为一名优秀教师

你是不是也有一个梦想&#xff0c;想要成为一位优秀的教师&#xff0c;让孩子们如沐春风&#xff0c;收获满满&#xff1f;那么&#xff0c;今天就让我来给你分享一下成为优秀教师的秘诀吧&#xff01; 热爱教育&#xff0c;点燃激情 成为优秀教师&#xff0c;首先要有对教育的…

C语言 - Linux基础使用

Linux 1. Linux简介 Linux是操作系统 Linux中所有的程序与硬件设备对Linux系统而言都是一个文件或文件夹 1.1 Linux发行版本 发型版本的名称/版本有发行方决定 Red Hat Enterprise Linux 5/6/7Suse Linux Enterprise 12Debian Linux 7.8Ubuntu Linux 14.10/15.04 1.2 Red H…

Vue与UserEcharts、DataV的协同

文章目录 引言一、Vue.js简介二、ECharts和UserEcharts1.ECharts简介2.UserEcharts&#xff1a;Vue和ECharts的结合 三、DataV简介四、Vue与DataV的结合1.DataV的Vue插件2.Vue和DataV的数据交互 结论我是将军&#xff0c;我一直都在&#xff0c;。&#xff01; 引言 接着上一篇…

基于协作搜索算法优化概率神经网络PNN的分类预测 - 附代码

基于协作搜索算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于协作搜索算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于协作搜索优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

卧室装修干货|榻榻米设计的3要点。福州中宅装饰,福州装修

榻榻米布局 1️⃣传统式布局 在房间中央设置书桌和衣柜&#xff0c;两侧留出走道空间。这种布局适合房间面积适中的房间。 2️⃣靠窗布局 将书桌靠窗放置&#xff0c;衣柜则放在书桌对面&#xff0c;这种布局可以充分利用自然光线&#xff0c;同时也节省空间。 3️⃣高低床…

C语言—二维数组

一、二维数组的创建 int arr[3][4];char arr[3][5];double arr[2][4]; 数组创建&#xff1a;“[ ]”中要给一个常量&#xff0c;不能使用变量 二、二维数组的初始化 int arr[3][4]{1,2,3,4};int arr[3][4]{{1,2},{4,5}};int arr[][4]{{2,3},{4,5}}; 前面的为行&#xff0c…

MySQL 索引相关问题,建议搭建好环境,真实操作一下索引应用到的各种场景

文章目录 什么是 B-tree 和 Btree &#xff1f;B-Tree 和 BTree的区别&#xff1f;MySQL 联合唯一索引是BTree&#xff0c;会带来什么原则&#xff1f;主键索引和单字段唯一索引有什么区别吗什么是 聚簇索引和非聚簇索引 &#xff1f;创建一个三百万数据量的表格&#xff0c;方…

邮政快递查询,邮政快递单号查询,用表格导出查询好的物流信息

批量查询邮政快递单号的物流信息&#xff0c;以表格的形式导出查询好的物流信息。 所需工具&#xff1a; 一个【快递批量查询高手】软件 邮政快递单号若干 操作步骤&#xff1a; 步骤1&#xff1a;运行【快递批量查询高手】软件&#xff0c;并登录 步骤2&#xff1a;点击主界…

GNSS介绍

GNSS介绍 1. GNSS概述2 GNSS工原理3 GNSS的关键技术3.1 RTK技术3.2 惯性导航技术 4 GPS导航电文的格式4.1 第一数据块4.2 第二数据块4.3 第三数据块 5 NMEA语句5.1 GGA5.2 GSA5.3 GSV5.4 RMC5.5 GLL5.6 VTG 6 各导航系统不同频段的工作频率7 LTE&#xff0c;GNSS&#xff0c;WI…

C语言,通过数组实现循环队列

实现循环队列最难的地方就在于如何判空和判满&#xff0c;只要解决了这两点循环队列的设计就没有问题。接下来我们将会使用数组来实现循环队列。 接下来&#xff0c;为了模拟实现一个容量为4的循环队列&#xff0c;我们创建一个容量为4 1 的数组。 接下来我们将会对这个数组…

ACL权限

ACL权限 目录&#xff1a; 1. 什么是ACL 2. 操作步骤 1. 什么是ACL ACL是Access Control List的缩写&#xff0c;即访问控制列表 每个项目成员在有一个自己的项目目录&#xff0c;对自己的目录有完全权限 项目组中的成员对项目目录也有完全权限 其他人对项目目录没有…

Selenium技巧大揭秘:动态数据、分页和Cookie的获取利器

背景&#xff1a; ​ 昨天我们讲了讲关于seleium的一些基础操作&#xff0c;今天讲讲如何将seleium和爬虫结合起来&#xff0c;可以使用selenium获取网页的动态加载数据&#xff0c;可以使用selenium获得cookie&#xff0c;这两个是比较常用的。我将一一展开。 实战案例&…

SAP Smartforms打印报错Error in spool C call : spool overflow

处理方式&#xff1a; SAP打印时提示&#xff1a; Error in spool C call : spool overflow (假脱机请求溢出&#xff0c;通俗一点打印池已满) 解决办法&#xff1a; SE38 首先运行程序RSPO1041 再运行RSPO1043&#xff0c;话不多说上图。

2023-11-24 LeetCode每日一题(统计和小于目标的下标对数目)

2023-11-24每日一题 一、题目编号 2824. 统计和小于目标的下标对数目二、题目链接 点击跳转到题目位置 三、题目描述 给你一个下标从 0 开始长度为 n 的整数数组 nums 和一个整数 target &#xff0c;请你返回满足 0 < i < j < n 且 nums[i] nums[j] < targe…

千梦网创:我回来了

最近小半年将近有5个月的时间基本没有更新什么大型的课程内容&#xff0c;朋友圈除了晨记没有频繁更新一些公告或者是动态&#xff0c;直到目前为止&#xff0c;我也才算把手头所有的事情全部梳理好&#xff0c;正式恢复更新状态。 这小半年发生了很多事情&#xff0c;有快乐的…