6、Qt—Log4Qt使用小记1

开发平台:Win10 64位

开发环境:Qt Creator 13.0.0 

构建环境:Qt 5.15.2 +MSVC2019 64位

一、Log4Qt简介

        Log4Qt是使用Trolltech Qt Framework的Apache Software Foundation Log4j包的C ++端口。它旨在供开源和商业Qt项目使用。所以 Log4Qt 是Apache Log4J 的Qt移植版,Log4Qt主要是用来记录日志(有助于程序调试)。henxin:

Logger提供日志记录服务,可以有多个Logger存在,每个有它们自己的名字。Logger间存在隶属关系,有一个Logger称为根Logger。
Appender用来指明将日志记录到什么地方:比如,控制台、文件、数据库,等等
Layout控制日志的输出格式,可以类比一下C中的printf。
Filter在日志消息被追加器处理之前进行筛选。 可以有多个筛选条件。
Level代表日志级别(如 TRACE< DEBUG< INFO< WARN< ERROR< FATAL)。 决定哪些日志消息应该被记录。 所以,如果你设置了 INFO 级别,那么 TRACE 和 DEBUG 消息将被忽略,而 INFO, WARN, ERROR, 和 FATAL 消息会被处理。同样地,如果设置为 ERROR 级别,那么只有 ERROR 和 FATAL 消息会被处理。
LoggingEvent代表一个日志事件,包含日志消息、时间戳、日志级别等信息。
LoggerRepository用于管理和检索日志器的容器。 默认实现是 LoggerRepository,但可以有其他实现。
LogManager提供静态方法管理日志器和配置。
Configuration 类这些类和方法允许从外部配置文件(如 XML 或 properties 文件)配置 Log4Qt。这样,开发者可以不修改代码即可更改日志配置。 PropertyConfigurator 和 XmlConfigurator 是两个主要的配置器类。

二、下载使用

2.1 下载说明

Qt4版本的log4qt当前最新版本为log4qt-0.3.zIP,这源码包最后修改日期为2009年。

Sourceforge下载地址:Log4Qt - Logging for C++/Qt download | SourceForge.net

Github:devbean/log4qt: Logger for Qt. (github.com)

Gitee: Gitee 极速下载/log4qt

笔者使用的QT版本是5.15.2,从github上面下载的log4qt源码,Releases · MEONMedical/Log4Qt (github.com),支持的QT版本为>5.12。

2.2 编译链接库 

将下载的Log4Qt解压,双击log4qt.pro,生成项目,然后右键选择重新构建项目。

在/build/Desktop_Qt_5_15_2_MSVC2019_64bit-Release/bin文件夹下就会生成log4qt.dll等文件。(具体路径根据自己选择的构建环境)。

现在我们需要的链接库就有了。

2.3 准备文件 

新建一个文件夹,在新建的文件夹下面在新建两个文件夹,一个是bin,一个是include,在include文件夹下面再新建一个log4qt文件夹。下面开始将源码中的文件依次倒入我们新建的这个文件夹中。首先将刚刚生成的链接库复制到bin文件夹中,然后将Log4Qt-master\src\log4qt路径下的三个文件夹和.h文件拷贝进include文件夹下面的log4gt文件夹中。

2.4 程序实现

上一步我们已经将log4qt的链接库、头文件等准备好了,现在开始通过代码的方式实现日志的配置和生成,下一小节通过配置文件来实现日志内容的配置和日志生成。新建工程,然后将新建的文件夹(log4qtlibs) 复制到工程目录下。

在untitled02.pro文件中增加如下代码:

DESTDIR = $$PWD/log4qtlibs/bin//这个要注意,exe及日志文件都会在这个目录下生成
INCLUDEPATH += $$PWD/log4qtlibs/include
LIBS += -L$$PWD/log4qtlibs/bin -llog4qt

更改main.cpp中的代码

#include "mainwindow.h"
#include <QApplication>
#include "log4qt/logger.h"
#include "log4qt/logmanager.h"
#include "log4qt/patternlayout.h"
#include "log4qt/consoleappender.h"
#include "log4qt/dailyfileappender.h"int main(int argc, char *argv[])
{QApplication a(argc, argv);//Logger:记录器,有一个根Logger,可以有多个其他LoggerLog4Qt::Logger *logger = Log4Qt::Logger::rootLogger(); //根Logger,name为root//Log4Qt::Logger *mylog1 = Log4Qt::Logger::logger("Mylog1");  //其他Logger,name为Mylog1的logger->setLevel(Log4Qt::Level::DEBUG_INT); //设置日志输出级别Log4Qt::LogManager::setHandleQtMessages(true); //处理qt调试输出信息,将qDebug之类的信息重定向,不开启这个qDebug()、qWri/****************PatternLayout配置日志的输出格式****************************/Log4Qt::PatternLayout *layout = new Log4Qt::PatternLayout();layout->setConversionPattern("%d{yyyy-MM-dd hh:mm:ss} %p %c %m %r %t %F %M %L %l %n");layout->activateOptions(); // 激活Layout/***************************配置日志的输出位置***********///ConsoleAppender:输出到控制台Log4Qt::ConsoleAppender *appender = new Log4Qt::ConsoleAppender(layout, Log4Qt::ConsoleAppender::STDOUT_TARGET);appender->activateOptions();logger->addAppender(appender);//DailyFileAppender:每天新建一个文件,保存当天的日志,超过指定的天数,删除最开始的日志Log4Qt::DailyFileAppender *dailiAppender = new Log4Qt::DailyFileAppender;dailiAppender->setLayout(layout); //设置输出格式dailiAppender->setFile("logFile.log"); //日志文件名:固定前缀dailiAppender->setDatePattern("_yyyy_MM_dd"); //日志文件名:根据每天日志变化的后缀dailiAppender->setAppendFile(true); //true表示消息增加到指定文件中,false则将消息覆盖指定的文件内容,默认值是falsedailiAppender->setKeepDays(30); //设置保留天数dailiAppender->activateOptions();logger->addAppender(dailiAppender);// 关闭 logger
//    logger->removeAllAppenders();
//    logger->loggerRepository()->shutdown();MainWindow w;w.show();return a.exec();
}

更改mainwindow.cpp中的代码

#include "mainwindow.h"
#include "ui_mainwindow.h"#include <QDebug>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);qDebug() << "mainwindow debug";qCritical() << "mainwindow critical";
}MainWindow::~MainWindow()
{delete ui;
}

重新构建,并运行,在项目目录的bin文件夹下生成日志文件

注意:如果是Debug模式下,可能MainWinwos中的这两句不能输出到日志文件中,需要改成release模式。

qDebug() << "mainwindow debug";
qCritical() << "mainwindow critical";

2.5 配置文件使用

使用配置文件首先得获取配置文件,log4qt提供了获取配置文件的函数

Log4Qt::PropertyConfigurator::configure(const QString &configFilename);

参数就是配置文件名,但是,直接填写参数名会报错,系统找不到。所以,对于配置文件,我们首先要明确配置文件放在哪?然后明确这个参数应该怎么写。

首先配置文件的位置可以放在任意可以访问的位置。然后这个参数就是配置文件的全路径。

Log4Qt::PropertyConfigurator::configure(a.applicationDirPath() + "/log4qt.ini");

笔者将这个 log4qt.ini放在了exe文件夹下,通过applicationDirPath函数,获取到exe的文件路径,然后拼接上文件名,就可以给configure函数配置文件的全路径了。

其实在参考文献3.5中有这么一种方式默认方案,但是不适合生产环境,毕竟我们使用配置文件的需求就是灵活性嘛,这种默认的需要文件名和地址都得符合log4qt的要求,不然log4qt找不到配置文件。

2.6 配置文件

#设置储存log文件的根目录
logpath=.log4j.reset=true
log4j.Debug=WARN
log4j.threshold=NULL
#设置是否监听QDebug输出的字符串
log4j.handleQtMessages=true
#在运行中,是否监视此文件配置的变化
log4j.watchThisFile=false#设置根Logger的输出log等级为Alllog4j.rootLogger=ALL, console, daily#设置Log输出的几种输出源(appender.console、appender.daily、appender.rolling):
#console:设置终端打印记录器
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.target=STDOUT_TARGET
log4j.appender.console.layout=org.apache.log4j.TTCCLayout
log4j.appender.console.layout.dateFormat=dd.MM.yyyy hh:mm:ss.zzz
log4j.appender.console.layout.contextPrinting=true
log4j.appender.console.threshold=ALL#daily:设置一个每日储存一个log文件的记录器
log4j.appender.daily=org.apache.log4j.DailyFileAppender
log4j.appender.daily.file=${logpath}/propertyconfigurator.log
log4j.appender.daily.appendFile=true
log4j.appender.daily.datePattern=_yyyy_MM_dd
log4j.appender.daily.keepDays=90
log4j.appender.daily.layout=${log4j.appender.console.layout}
log4j.appender.daily.layout.dateFormat=${log4j.appender.console.layout.dateFormat}
log4j.appender.daily.layout.contextPrinting=${log4j.appender.console.layout.contextPrinting}#rolling:配置一个滚动文件记录器
log4j.appender.rolling=org.apache.log4j.RollingFileAppender
log4j.appender.rolling.file= ${logpath}/propertyconfigurator_rolling.log
log4j.appender.rolling.appendFile=true
log4j.appender.rolling.maxFileSize= 20MB
log4j.appender.rolling.maxBackupIndex= 10
log4j.appender.rolling.layout=${log4j.appender.console.layout}
log4j.appender.rolling.layout.dateFormat=${log4j.appender.console.layout.dateFormat}
log4j.appender.rolling.layout.contextPrinting=${log4j.appender.console.layout.contextPrinting}# 给“LoggerObjectPrio”这个类的Logger定义log输出等级为Error,
# 给“LoggerObjectPrio”这个类的Logger定义log输出源:daily, console
log4j.logger.LoggerObjectPrio=ERROR, rolling
#设置为false,表示“LoggerObjectPrio”这个类的logger不继承的rootLogger输出源(appender)
log4j.additivity.LoggerObjectPrio=false
log4j.rootLogger=debug,File
log4j.appender.File=org.apache.log4j.FileAppender
log4j.appender.File=org.apache.log4j.RollingFileAppender
log4j.appender.File.File=Log.log
log4j.appender.File.MaxFileSize=3072KB
log4j.appender.File.AppendFile=true
log4j.appender.File.layout=org.apache.log4j.PatternLayout
log4j.appender.File.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%p] %m%n(1)org.apache.log4j.ConsoleAppender(控制台)
(2)org.apache.log4j.FileAppender(文件)
(3)org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
(4)org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
(5)org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)(1)ConsoleAppender选项:
Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG。
ImmediateFlush=true:表示所有消息都会被立即输出,设为false则不输出,默认值是true。
Target=System.err:默认值是System.out。(2)FileAppender选项:
Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG。
ImmediateFlush=true:表示所有消息都会被立即输出,设为false则不输出,默认值是true。
Append=false:true表示消息增加到指定文件中,false则将消息覆盖指定的文件内容,默认值是true。
File=D:/logs/logging.log4j:指定消息输出到logging.log4j文件中。(3)DailyRollingFileAppender选项:
Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG。
ImmediateFlush=true:表示所有消息都会被立即输出,设为false则不输出,默认值是true。
Append=false:true表示消息增加到指定文件中,false则将消息覆盖指定的文件内容,默认值是true。
File=D:/logs/logging.log4j:指定当前消息输出到logging.log4j文件中。
DatePattern=’.‘yyyy-MM:每月滚动一次日志文件,即每月产生一个新的日志文件。当前月的日志文件名为logging.log4j,前一个月的日志文件名为logging.log4j.yyyy-MM。
另外,也可以指定按周、天、时、分等来滚动日志文件,对应的格式如下:
1)’.‘yyyy-MM:每月
2)’.‘yyyy-ww:每周
3)’.‘yyyy-MM-dd:每天
4)’.‘yyyy-MM-dd-a:每天两次
5)’.‘yyyy-MM-dd-HH:每小时
6)’.'yyyy-MM-dd-HH-mm:每分钟(4)RollingFileAppender选项:
Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG。
ImmediateFlush=true:表示所有消息都会被立即输出,设为false则不输出,默认值是true。
Append=false:true表示消息增加到指定文件中,false则将消息覆盖指定的文件内容,默认值是true。
File=D:/logs/logging.log4j:指定消息输出到logging.log4j文件中。
MaxFileSize=100KB:后缀可以是KB, MB 或者GB。在日志文件到达该大小时,将会自动滚动,即将原来的内容移到logging.log4j.1文件中。
MaxBackupIndex=2:指定可以产生的滚动文件的最大数,例如,设为2则可以产生logging.log4j.1,logging.log4j.2两个滚动文件和一个logging.log4j文件。配置日志信息的输出格式(Layout):
log4j.appender.appenderName.layout=className
className:可设值如下:
(1)org.apache.log4j.HTMLLayout(以HTML表格形式布局)
(2)org.apache.log4j.PatternLayout(可以灵活地指定布局模式)
(3)org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)
(4)org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)(1)HTMLLayout选项:
LocationInfo=true:输出java文件名称和行号,默认值是false。
Title=My Logging: 默认值是Log4J Log Messages。(2)PatternLayout选项:
ConversionPattern=%m%n:设定以怎样的格式显示消息。
格式化符号说明:
%p:输出日志信息的优先级,即DEBUG,INFO,WARN,ERROR,FATAL。
%d:输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,如:%d{yyyy/MM/dd HH:mm:ss,SSS}。
%r:输出自应用程序启动到输出该log信息耗费的毫秒数。
%t:输出产生该日志事件的线程名。
%l:输出日志事件的发生位置,相当于%c.%M(%F:%L)的组合,包括类全名、方法、文件名以及在代码中的行数。例如:test.TestLog4j.main(TestLog4j.java:10)。
%c:输出日志信息所属的类目,通常就是所在类的全名。
%M:输出产生日志信息的方法名。
%F:输出日志消息产生时所在的文件名称。
%L::输出代码中的行号。
%m::输出代码中指定的具体日志信息。
%n:输出一个回车换行符,Windows平台为"/r/n",Unix平台为"/n"。
%x:输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。
%%:输出一个"%“字符。
另外,还可以在%与格式字符之间加上修饰符来控制其最小长度、最大长度、和文本的对齐方式。如:1)%20c:指定输出category的名称,最小的长度是20,如果category的名称长度小于20的话,默认的情况下右对齐。
2)%-20c:”-"号表示左对齐。
3)%.30c:指定输出category的名称,最大的长度是30,如果category的名称长度大于30的话,就会将左边多出的字符截掉,但小于30的话也不会补空格。
log4j.logger.debug=CONSOLE,debug
log4j.appender.debug=org.apache.log4j.RollingFileAppender
log4j.appender.debug.Threshold=DEBUG
log4j.appender.debug.appendFile=true
log4j.appender.debug.Encoding=UTF-8
log4j.appender.debug.File=log/debug.txt
log4j.appender.debug.MaxFileSize=4096KB
log4j.appender.debug.MaxBackupIndex=7
log4j.appender.debug.layout=org.apache.log4j.PatternLayout
log4j.appender.debug.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.zzz}[%t][%p] %m%nlog4j.logger.info=CONSOLE,info,debug
log4j.appender.info=org.apache.log4j.RollingFileAppender
log4j.appender.info.Threshold=DEBUG
log4j.appender.info.appendFile=true
log4j.appender.info.Encoding=UTF-8
log4j.appender.info.File=log/info.txt
log4j.appender.info.MaxFileSize=4096KB
log4j.appender.info.MaxBackupIndex=7
log4j.appender.info.layout=org.apache.log4j.PatternLayout
log4j.appender.info.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.zzz}[%t][%p] %m%nlog4j.logger.warn=CONSOLE,info,debug,warn
log4j.appender.warn=org.apache.log4j.RollingFileAppender
log4j.appender.warn.Threshold=DEBUG
log4j.appender.warn.appendFile=true
log4j.appender.warn.Encoding=GBK
log4j.appender.warn.File=log/warn.txt
log4j.appender.warn.MaxFileSize=4096KB
log4j.appender.warn.MaxBackupIndex=2
log4j.appender.warn.layout=org.apache.log4j.PatternLayout
log4j.appender.warn.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.zzz}[%t][%p] %m%nlog4j.logger.error=CONSOLE,info,debug,warn,error
log4j.appender.error=org.apache.log4j.RollingFileAppender
log4j.appender.error.Threshold=DEBUG
log4j.appender.error.appendFile=true
log4j.appender.error.Encoding=UTF-8
log4j.appender.error.File=log/error.txt

还是要重点说明下,生产环境下一般这个配置文件储存在软件可执行文件所在的目录。log文件储存的位置由配置文件配置。

mian.cpp中的代码是设置日志输出格式:
layout->setConversionPattern("%d{yyyy-MM-dd hh:mm:ss} %p %c %m %r %t %F %M %L %l %n");
输出的对应内容如下:
%d{yyyy-MM-dd hh:mm:ss}:2023-10-27 10:31:19 
%p:DEBUG 
%c:Qt default 
%m:mainwindow debug 
%r:1454 
%t:0x000000000d816d00 
%F:..\log4qtlibs\mainwindow.cpp 
%M:MainWindow::MainWindow(QWidget*) 
%L:11 
%l:..\log4qtlibs\mainwindow.cpp:11 - MainWindow::MainWindow(QWidget*)
%n:换行

三、参考文献

3.1 Qt使用Log4Qt日志-CSDN博客

3.2 log4Qt史上最详细介绍、编译和使用-CSDN博客

3.3 使用 log4qt.properties 配置 Log4Qt-轻识 (qinglite.cn) 

3.4 Qt扩展-Log4Qt 简介及配置_qt log4qt-CSDN博客 

3.5 使用 log4qt.properties 配置 Log4Qt-轻识 (qinglite.cn) 

3.6 12.4-在Qt中使用Log4Qt输出Log文件,看这一篇就足够了_qt log4qt-CSDN博客

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

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

相关文章

Java零拷贝技术实战

文章目录 引入传统IO内存映射mmap文件描述符sendFile测试总结 引入 为什么要使用零拷贝技术&#xff1f; 传统写入数据需要4次拷贝&#xff0c;如下图&#xff1a; 传统IO import java.io.*; import java.net.Socket;public class TranditionIOClient {private static fina…

【机器学习300问】81、什么是动量梯度下降算法?

动量梯度下降算法&#xff08;Momentum&#xff09;是利用指数加权移动平均的思想来实现梯度下降的算法。让我们先来回顾一下基础的梯度下降方法以及看看它有哪些不足之处。接着引出动量梯度下降算法&#xff0c;在理解了它的原理后看看它是如何规避之前方法的不足的。 如果不知…

网络安全ctf比赛_学习资源整理,解题工具、比赛时间、解题思路、实战靶场、学习路线,推荐收藏!...

对于想学习或者参加CTF比赛的朋友来说&#xff0c;CTF工具、练习靶场必不可少&#xff0c;今天给大家分享自己收藏的CTF资源&#xff0c;希望能对各位有所帮助。 CTF在线工具 首先给大家推荐我自己常用的3个CTF在线工具网站&#xff0c;内容齐全&#xff0c;收藏备用。 1、C…

使用 RyTuneX 增强您的 Windows 10 和 11 体验 – Rayen Ghanmi 的首选优化器。

&#x1f4dd; 关于 RyTuneX 是使用 WinUI 3 框架构建的尖端优化器&#xff0c;旨在增强 Windows 设备&#x1f680;的性能。 RyTuneX 专为 Windows 10 和 11 打造&#xff0c;使用户能够毫不费力地删除顽固的预装应用程序并优化系统资源&#x1f6e0;️。 &#x1f680; 功能…

微信加粉计数器

1.采用非注入式开发&#xff0c;支持无限多开 2.每个账号都有独立的分组&#xff0c;实时远程网页数据分享 3.后台功能强大&#xff0c;操作简单&#xff0c;自动去重复&#xff0c;准确计数分秒不差

Java毕业设计 基于SpringBoot vue药店管理系统

Java毕业设计 基于SpringBoot vue药店管理系统 SpringBoot 药店管理系统 功能介绍 员工 登录 个人中心 修改密码 个人信息 查看供应商信息 查看药品 查看进货 查看销售 管理员 登录 个人中心 修改密码 个人信息 供应商类型管理 供应商信用等级类型管理 药品类型管理 供应商信…

不懂数字后端Box List、Polygon的意思?

什么是BOX&#xff1f; 景芯SoC做design planning的第一步就是确定floorplan的box&#xff0c;也就是设计的区域。这个区域可以划分为三个边界&#xff0c;如下图所示&#xff1a; Die Box 最外面一圈&#xff0c;我们称为 Die Box&#xff0c;也就是用来放置 IO 单元&#x…

太阳能无人机的多元化应用

随着新能源技术的不断发展和成熟&#xff0c;太阳能在无人机的应用技术已经成熟。太阳能无人机得到了量产和广泛的应用。传统无人机相比&#xff0c;太阳能无人机无需燃油&#xff0c;运行费用低廉&#xff0c;搭载多种高科技设备&#xff0c;能够高效、多元化地采集和分析各类…

汇昌联信电商:拼多多网店好做吗?

在电子商务的海洋中&#xff0c;拼多多以其独特的团购模式和亲民策略迅速崛起&#xff0c;吸引了大批消费者和商家的目光。对于“拼多多网店好做吗?”这个问题&#xff0c;答案并非简单的是与否&#xff0c;而是需要从多个维度进行深入分析。 一、市场定位与竞争环境 拼多多定…

常见 Web 安全攻防总结

Web 安全的对于 Web 从业人员来说是一个非常重要的课题&#xff0c;所以在这里总结一下 Web 相关的安全攻防知识&#xff0c;希望以后不要再踩雷&#xff0c;也希望对看到这篇文章的同学有所帮助。今天这边文章主要的内容就是分析几种常见的攻击的类型以及防御的方法。 也许你对…

05-10 周五 推理是什么

05-10 周五 推理是什么 时间版本修改人描述2024年5月10日10:13:54V0.1宋全恒新建文档2024年5月13日11:08:42V1.0宋全恒填充了训练和推理的定义&#xff0c;并且对于推理加速的方面进行了详细的介绍 简介 最近要坐推理时的动态量化&#xff0c;因此&#xff0c;需要认真理解一下…

独立游戏《星尘异变》UE5 C++程序开发日志3——实现一个存存组件

本篇日志中&#xff0c;我将会介绍如何实现一个有格子&#xff0c;每个格子有容量的物品库存&#xff0c;如下图&#xff1a; 一.库存容器 1.储存数据的容器 库存容器最重要的目的就是存储每一种类的物品拥有的数量&#xff0c;这里我用的是哈希表&#xff1a; std::unordere…

huggingface:利用git克隆目标资源

前言 因为有很多模型资源都被放在了huggingface上&#xff0c;为了下载它们&#xff0c;着实让一个不懂git的人犯了难&#xff0c;绕了很多远路&#xff0c;甚至将不需要解决的问题也都拿上了台面&#xff0c;因此我将在本篇博客中记载一些关于【huggingface】中利用git克隆目标…

【c++】全面理解C++多态:虚函数表深度剖析与实践应用

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 朋友们大家好&#xff0c;通过本篇文章&#xff0c;来详细理解多态的内容 目录 1.多态的定义及实现1.1多态的构成条件1.2虚函数的重写1.3 C11 override 和 final1.4重载、覆盖(重写)、隐藏…

鸿蒙内核源码分析 (内核启动篇) | 从汇编到 main ()

这应该是系列篇最难写的一篇&#xff0c;全是汇编代码&#xff0c;需大量的底层知识&#xff0c;涉及协处理器&#xff0c;内核镜像重定位&#xff0c;创建内核映射表&#xff0c;初始化 CPU 模式栈&#xff0c;热启动&#xff0c;到最后熟悉的 main() 。 内核入口 在链接文件…

在k8s中安装Grafana并对接Prometheus,实现k8s集群监控数据的展示

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Grafana&#xff1a;让数据说话的魔术师》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Grafana简介 2、Grafana的重要性与影响力 …

强化训练:day9(添加逗号、跳台阶、扑克牌顺子)

文章目录 前言1. 添加逗号1.1 题目描述2.2 解题思路2.3 代码实现 2. 跳台阶2.1 题目描述2.2 解题思路2.3 代码实现 3. 扑克牌顺子3.1 题目描述3.2 解题思路3.3 代码实现 总结 前言 1. 添加逗号   2. 跳台阶   3. 扑克牌顺子 1. 添加逗号 1.1 题目描述 2.2 解题思路 我的写…

STM32学习和实践笔记(28):printf重定向实验

1.printf重定向简介 在C语言中printf函数里&#xff0c;默认输出设备是显示器&#xff0c;如果想要用这个函数将输出结果到串口或者LCD上显示&#xff0c;就必须重定义标准库函数里中printf函数调用的与输出设备相关的函数。 比如要使用printf输出到串口&#xff0c;需要先将f…

linux 任务管理(临时任务定时任务) 实验

目录 任务管理临时任务管理周期任务管理 任务管理 临时任务管理 执行如下命令添加单次任务&#xff0c;输入完成后按组合键Ctrl-D。 [rootopenEuler ~]# at now5min warning: commands will be executed using /bin/sh at> echo "aaa" >> /tmp/at.log at&g…

J-STAGE (日本电子科学与技术信息集成)数据库介绍及文献下载

J-STAGE (日本电子科学与技术信息集成)是日本学术出版物的平台。它由日本科学技术振兴机构&#xff08;JST&#xff09;开发和管理。该系统不仅包括期刊&#xff0c;还有论文集&#xff0c;研究报告、技术报告等。文献多为英文&#xff0c;少数为日文。目前网站上所发布的内容来…