目录
本章主要是学习和使用本项目中所需使用到的一些框架。
gflags
介绍
gflags是google开发的一个开源库,用于C++程序中命令行参数的声明、定义和解析。
gflags提供了一种简单的方式来添加、解析和文档化命令行标志,使得程序可以根据不同的运行时配置来调整。
gflags的特点:
易于使用 | 提供了一套简单直观的API来定义和解析命令行标志。 |
自动帮助和文档 | gflags可以自动生成每个标志的帮助信息和文档。 |
类型安全 | gflags支持多种数据类型的标志,包括布尔值、整数、字符串等,并且提供了类型转换和检查。 |
多平台性 | 可以在多种操作系统上使用,如Windows、Linux。 |
可扩展性 | 允许开发者自定义标志的注册和解析逻辑。 |
安装
命令安装:
sudo apt-get install libgflags-dev
使用
头文件包含
#include <gflags/gflags.h>
编译时指明库
-l gflags
例如写Makefile时:
g++ $^ -o $@ -std=c++17 -lgflags
宏定义参数
gflags提供了它自己的宏,让我们来定义参数。该宏有三个参数:参数名、参数默认值、参数说明(注释)。
其中gflags支持的宏定义类型:
DEFINE_bool
DEFINE_int32
DEFINE_int64
DEFINE_uint64
DEFINE_double
DEFINE_string
使用样例:
DEFINE_bool(reuser_addr, true, "是否启动地址重用, 默认: yes");
DEFINE_int32(log_level, 1, "日志等级: 1-DEBUG, 2-WARN, 3-ERROR");
DEFINE_string(log_file, "stdout", "日志输出文件, 默认: stdout");
启动时设置命令行参数来设置参数值
gflags为我们提供了多种设置命令行参数的方式,支持我们在运行程序的时候,以命令行参数的形式传入参数的值。
注意:这里不是定义新的参数,而是设置我们已经定义号的参数的值!
shell: ./a.out exec --log_level=2
shell: ./a.out exec --log_file="stderr"
shell: ./a.out exec --reuse_addr=false
使用配置文件来设置参数值
除了使用命令行参数的形式来设置参数值,也可以、更推荐使用配置文件的方式来设置参数值。
main.conf:
-reuse_addr=false
-log_level=2
-log_file="stderr"
此时运行程序的时候,需要指定该程序从哪个配置文件里读取参数:
-flagfile=xxx #从xxx这个配置文件中读取参数
同样注意:配置文件中的参数名也必须和代码中定义的参数名一样。
初始化所有参数
当我们定义好参数后,并不能直接使用,需要用gflags提供的API将我们定义的参数进行初始化解析后,才能正常使用。
int main(int argc, char *argv[])
{
google::ParseCommandLineFlags(&argc, &argv, true);
}
其中argc和argv就是main函数的参数。
第三个参数称为remove_flags。true:在解析命令行参数后,argc和argv会被修改,移除已解析的标志。这意味着后续代码将无法再访问这些标志,因为它们已经从argv中移除。
比如上述定义的reuse_addr,如果这里我们用的true,那么在解析之后,argv中将不再含有 --reuse_addr的标志。
true:通常在你希望清理命令行参数,使得后续代码不会误处理这些标志时使用。
访问参数
在程序中不能直接按照变量名去使用参数,gflags规定,在使用其定义的参数时,必须加上前缀FLAGS_来使用。
FLAGS_reuse_addr;
FLAGS_log_level;
FLAGS_log_file;
程序B访问程序A定义的参数
在程序B中想要访问程序A的参数,需要先声明。
gflags提供了宏DECLARE来声明参数。
DECLARE_bool(reuse_addr);
DECLARE_int32(log_level);
DECLARE_string(log_file);
gflags提供的特殊参数标识
--help | 显示文件中所有标识的帮助信息 |
--helpfull | 比--help显示的信息更加全面 |
--helpshort | 只显示当前执行文件里的标志 |
--helpxml | 以XML方式进行打印,方便处理 |
--version | 打印版本信息,由google::SetVersionString()设定 |
--flagfile | 指定配置文件 |
使用案例
代码编写
main.cc
#include <gflags/gflags.h>
#include <iostream>
DEFINE_bool(reuser_addr, true, "是否启动地址重用, 默认: yes");
DEFINE_int32(log_level, 1, "日志等级: 1-DEBUG, 2-WARN, 3-ERROR");
DEFINE_string(log_file, "stdout", "日志输出文件, 默认: stdout");
int main(int argc, char *argv[])
{
google::ParseCommandLineFlags(&argc, &argv, true);
std::cout << "reuse: " << FLAGS_reuser_addr << std::endl;
std::cout << "log_level: " << FLAGS_log_level << std::endl;
std::cout << "log_file: " << FLAGS_log_file << std::endl;
return 0;
}
配置文件main.conf
-reuse_addr=false
-log_level=3
-log_file="stderr"
Makefile
main:main.cc
g++ $^ -o $@ -std=c++17 -lgflags
样例运行
shell$ ./main --flagfile=main.conf
reuse: 1
log_level: 3
log_file: "stderr"
gtest
介绍
gtest是一个google开发的跨平台的C++单元测试框架,是为了在不同的平台上为编写C++单元测试而生成的。
它提供了丰富的断言、致命和非致命判断、参数化等等测试所需要的宏,以及全局测试、单元测试组件。
安装
命令安装:
sudo apt-get install libgtest-dev
使用
头文件包含
#include <gtest/gtest.h>
编译时指明库
-l gtest
gtest框架初始化接口
想要使用gtest进行单元测试之前,必须进行框架的初始化。
int main(int argc, char *argv[])
{
testing::InitGoogleTest(&argc, argv);
return 0;
}
测试样例TEST宏
TEST(测试名称, 测试样例)
TEST_F(test_fixture, test_name)
TEST:主要用来创建一个简单测试,定义一个测试函数。
TEST_F:主要用来进行多样测试,适用于多个测试场景如果需要相同的数据配置的情况。
断言宏
gtest中的断言宏一般分为两类。
ASSERT_系列:如果当前点检测失败,就退出当前函数。
EXPECT_系列:如果当前点检测失败,继续向下执行。
经常使用的断言介绍:
ASSERT_TRUE(x) | 期待x的结果是true |
ASSERT_FALSE(x) | 期待x的结果是false |
ASSERT_EQ(a , b) | 期待a 等于b |
ASSERT_NE(a, b) | 期待a 不等于 b |
ASSERT_LT(a, b) | 期待a 小于 b |
ASSERT_GT(a , b) | 期待 a 大于b |
ASSERT_LE(a , b) | 期待 a 小于等于b |
ASSERT_GE(a , b) | 期待 a大于等于 b |
使用案例
代码编写
main.cc
#include <gtest/gtest.h>
#include <iostream>
int abs(int x)
{
return x > 0 ? x : -x;
}
TEST(abs_test, test1)
{
ASSERT_TRUE(abs(1) == 1) << "abs(1)=1";
ASSERT_TRUE(abs(-1) == 1);
ASSERT_FALSE(abs(-2) == -2);
ASSERT_EQ(abs(1), abs(-1));
ASSERT_NE(abs(-1), 0);
ASSERT_LT(abs(-1), 2);
ASSERT_GT(abs(-1), 0);
ASSERT_LE(abs(-1), 2);
ASSERT_GE(abs(-1), 0);
}
int main(int argc, char *argv[])
{
testing::InitGoogleTest(&argc, argv);
RUN_ALL_TESTS();
return 0;
}
Makefile
main:main.cc
g++ $^ -o $@ -std=c++17 -lgtest
样例运行
shell $ ./main
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from abs_test
[ RUN ] abs_test.test1
[ OK ] abs_test.test1 (0 ms)
[----------] 1 test from abs_test (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[ PASSED ] 1 test.
spdlog
介绍
spdlog是一个高性能、超快速、零配置的C++日志库,旨在提供简洁的API和丰富的功能,同时保持高性能的日志记录。
它支持多种输出目标、格式化选项、线程安全以及异步日志记录。
spdlog的特点:
高性能 | spdlog专为速度而设计,即时在高负载的情况下也能保持良好的性能。 |
零配置 |