当前位置: 首页 > article >正文

std::chrono类的简单使用实例及分析


author: hjjdebug
date: 2025年 05月 20日 星期二 14:36:17 CST
descrip: std::chrono类的简单使用实例及分析


文章目录

  • 1.实例代码:
  • 2. 代码分析:
    • 2.1 auto t1 = std::chrono::high_resolution_clock::now();
      • 2.1.1 什么是 system_clock
      • 2.1.2 什么是 chrono::time_point?
      • 2.1.3 什么是duration?
        • 2.1.3.1 duration 的一个实例
      • 2.1.4 这么多的内涵,到底怎样理解time_point呢?
      • 2.1.5 time_point t1 在gdb中的表示
    • 2.2 auto delta_t = t2 - t1;
    • 2.3 auto dur_obj = std::chrono::duration<double, std::milli>(delta_t);
      • 2.3.1 duration 对象能够知道数值代表的是毫秒,纳秒或者其它单位吗?

1.实例代码:

$ cat main.cpp
#include <iostream>
#include <unistd.h> //for sleep
#include <chrono>
using namespace std;int main() {//now()是类的静态函数, auto t1 = std::chrono::high_resolution_clock::now(); //t1 是time_point 对象, time_point 对象是什么?// 被测代码sleep(1);auto t2 = std::chrono::high_resolution_clock::now();  // 返回的是时间点对象auto delta_t = t2 - t1; //2个time_point 对象相减,肯定被重构了. 返回的是 duration 对象, duration 对象是什么?auto dur_obj = std::chrono::duration<double, std::milli>(delta_t); //构造函数,参数是duration对象,返回ms为单位的duration对象std::cout << "耗时:" << dur_obj.count() << "ms" <<endl; //访问其数值,通过count(), 我们构建的是ms为单位的对象,所以单位就是msdur_obj = std::chrono::duration<double, std::milli>(500); //另一个构造函数,给500就打印500,单位还是ms,由std::milli类型决定的.std::cout << "测试打印:" << dur_obj.count() << "ms" <<endl;return 0;
}

执行结果
$ ./temp
耗时:1000.14ms
测试打印:500ms

代码很短,可是内涵很丰富. 是c++模板类的入门之路.
下面几乎是逐句分析了.

2. 代码分析:

2.1 auto t1 = std::chrono::high_resolution_clock::now();

std: namespace
chrono: namespace
大命名空间下的小命名空间,此时的命名空间为std::chrono
using high_resolution_clock = system_clock;
using 与typedef 类似, 也与#define 有可比性. 就是说high_resolution_clock 这个类型
是 system_clock 类型的小名, 它们是一个类型. 由此引出 system_clock 类型

2.1.1 什么是 system_clock

    struct system_clock{ //定义了一堆类型别名, 告诉编译器说, 别慌, 有一堆类型记住它们的小名.typedef chrono::nanoseconds duration; //使用ns做durationtypedef duration::rep rep;typedef duration::period period;typedef chrono::time_point<system_clock, duration> time_point;//静态变量是属于类的变量, 是全局的.static constexpr bool is_steady = false;//静态函数是属于类的函数. 恰似普通的函数, 执行不使用this指针,有3个//成员函数 now() to_time_t(time_point &t), from_time_t(std::time_t t)static time_point now() noexcept;static std::time_tto_time_t(const time_point& __t) noexcept{return std::time_t(duration_cast<chrono::seconds>(__t.time_since_epoch()).count());}static time_pointfrom_time_t(std::time_t __t) noexcept{typedef chrono::time_point<system_clock, seconds> __from;return time_point_cast<system_clock::duration>(__from(chrono::seconds(__t)));}};

now 是system_clock 类的静态成员函数, 返回一个time_point 类型对象

2.1.2 什么是 chrono::time_point?

看一下它的声明,
template<class Clock, class Duration = typename Clock::duration> class time_point;
它是一个类模板. 有两个类型参数.
时钟类型决定了时间的来源, 有system_clock, steady_clock,high_resolution_clock(是system_clock的代名词)

system_clock, 前面已经有交代.
剧透一下 system_clock 的纪元为 1970-01-01 00:00:00 UTC), unix时间戳起点
system_clock是time_point类模板的第一个参数.

time_point类模板的第二个参数类型duration 是什么?

2.1.3 什么是duration?

duration 是一个类型,这里先给duration的一个实例.

2.1.3.1 duration 的一个实例
(gdb) ptype dur_obj
type = struct std::chrono::duration<double, std::ratio<1, 1000> > [with _Rep = double, _Period = std::ratio<1, 1000>] {private:_Rep __r;public:duration(void);duration(const std::chrono::duration<_Rep, _Period> &);~duration();std::chrono::duration<_Rep, _Period> & operator=(const std::chrono::duration<_Rep, _Period> &);_Rep count(void) const;std::chrono::duration<_Rep, _Period> operator+(void) const;std::chrono::duration<_Rep, _Period> operator-(void) const;std::chrono::duration<_Rep, _Period> & operator++(void);std::chrono::duration<_Rep, _Period> operator++(int);std::chrono::duration<_Rep, _Period> & operator--(void);std::chrono::duration<_Rep, _Period> operator--(int);std::chrono::duration<_Rep, _Period> & operator+=(const std::chrono::duration<_Rep, _Period> &);std::chrono::duration<_Rep, _Period> & operator-=(const std::chrono::duration<_Rep, _Period> &);std::chrono::duration<_Rep, _Period> & operator*=(const _Rep &);std::chrono::duration<_Rep, _Period> & operator/=(const _Rep &);static std::chrono::duration<_Rep, _Period> zero(void);static std::chrono::duration<_Rep, _Period> min(void);static std::chrono::duration<_Rep, _Period> max(void);void duration<int>(const int &);void duration<double>(const _Rep &);void duration<long, std::ratio<1, 1000000000> >(const std::chrono::duration<long, std::ratio<1, 1000000000> > &);typedef _Rep rep;
}

它有一个私有成员变量 _Rep __r, __Rep 是represent的简写, 是类模板的第一个类型参数.可能是double或long
类模板还有第2个类型参数, 此处是 std::ratio<1,1000> 类型, 这个类型起码有2个类属性可以使用
std::ratio<1,1000>::num=1
std::ratio<1,1000>::den=1000
至于其它构造,析构,重载运算符就不具体分析了.

2.1.4 这么多的内涵,到底怎样理解time_point呢?

时间点对象timepoint是时间点类模板用system_clock 和 nanoseconds 为类型参数实例化后的一个对象.它有一个duration类型的变量记录其属性
其值说明是从 1970-01-01 00:00:00 开始的 纳秒数, 用long int 表示的数

2.1.5 time_point t1 在gdb中的表示

time_point 包含一个duration 对象 __d, duration对象包含一个实现类型(long或double)变量 __r
(gdb) p t1
$1 = {
__d = {
__r = 1747640811095678930 //1970-01-01 00:00:00开始的时间, 单位仅从对象本身是看不出来的.
}
}
//从类模板类型参数上知道它是ns, 但模板类型参数仅仅是编译期属性, 编译期知道它是ns, 但运行期就不知道了.

(gdb) ptype t1 , 
type = struct std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1, 1000000000> > > [with _Clock = std::chrono::_V2::system_clock, _Dur = std::chrono::duration<long, std::ratio<1, 1000000000> >] {private:_Dur __d;  //私有成员变量, duration 类型public:time_point(void);time_point(const _Dur &);_Dur time_since_epoch(void) const;std::chrono::time_point<_Clock, _Dur> & operator+=(const _Dur &);std::chrono::time_point<_Clock, _Dur> & operator-=(const _Dur &);static std::chrono::time_point<_Clock, _Dur> min(void);static std::chrono::time_point<_Clock, _Dur> max(void);typedef _Dur duration;
}(gdb) p t2
$2 = {__d = {__r = 1747640813823889979 //unix 时间点到现在的时间间隔}
}

2.2 auto delta_t = t2 - t1;

//两个时间点之差是duration 变量
//2个time_point 对象相减,运算被重构了. 返回的是 duration 对象
(gdb) p delta_t //一种duration 对象
$3 = {
__r = 2728211049
}
(gdb) p dur_obj //另一种duration 对象
$4 = {
__r = 2728.211049
}

2.3 auto dur_obj = std::chrono::duration<double, std::milli>(delta_t);

代码分析:
std::chrono namespace
duration<double, std::milli>: 是一个实例化模板类
std::chrono::duration<double,std::milli>(delta_t);
类名称后面跟上一个参数(这里是duration为参数)就是构建对象的过程(copy构造)
auto dur_obj = std::chrono::duration<double, std::milli>(delta_t); (赋值构造)
把一个无名对象赋值给一个有名对象 dur_obj

duration 对象是什么?数值代表了什么意思?
请参考2.1.4 说明duration 对象是什么类型

2.3.1 duration 对象能够知道数值代表的是毫秒,纳秒或者其它单位吗?

答: 对于一个duration 对象
$4 = {
__r = 2728.211049
}
duration 本身并不知道数值代表的是ms,ns或其它单位.
但是duration类却能够根据构造函数传来的类型及模板参使用的类型对传来的数值进行转换.
这是静态编译的能力.
现在已经计算出了这个值并付给了对象的成员. 但这个对象已经不知道自己是什么单位了,
因为对象本身没有保留单位信息. 即单位信息做为模板类型参数不是运行期特性只是编译期特性.

那我们怎么知道数值的单位是什么呢?
这是你自己的问题, 你自己根据数值的转变过程确定它应该是什么单位.

http://www.lryc.cn/news/2383985.html

相关文章:

  • Git命令汇总(自用,持续更新update 5/23)
  • window xampp apache使用腾讯云ssl证书配置https
  • MATLAB求解二元一次方程组基础教程
  • Android13 wifi设置国家码详解
  • 逆向音乐APP:Python爬虫获取音乐榜单 (1)
  • JVM 垃圾回收器
  • Java合并两个列表到目标列表,并且进行排序
  • Spring AI Alibaba集成阿里云百炼大模型应用
  • 22. 用例依赖装饰器的实现思路和方法
  • 支持向量存储:PostgresSQL及pgvector扩展详细安装步骤!老工程接入RAG功能必备!
  • 【部署】如何离线环境创建docker容器执行python命令行程序
  • idea常用配置 properties中文输出乱码
  • 【Bluedroid】蓝牙 HID Host connect全流程源码解析
  • day1 大模型学习 Qwen系列学习
  • Unity3D仿星露谷物语开发47之砍树时落叶特效
  • 第十节第六部分:常见API:DateTimeFormatter、Period、Duration
  • 如何在VSCode中更换默认浏览器:完整指南
  • B2160 病人排队
  • 【机器人】复现 3D-Mem 具身探索和推理 | 3D场景记忆 CVPR 2025
  • 鸿蒙进阶——CMakelist、GN语法简介及三方库通用移植指南
  • CSS-5.1 Transition 过渡
  • TTS:VITS-fast-fine-tuning 快速微调 VITS
  • 从虚拟仿真到行业实训再到具身智能--华清远见嵌入式物联网人工智能全链路教学方案
  • 告别手动绘图!2分钟用 AI 生成波士顿矩阵
  • GraphPad Prism工作表的管理
  • UE 材质几个输出向量节点
  • 【modelscope/huggingface 通过colab将huggingface 模型/数据集/空间转移到 modelscope并下载】
  • 告别静态UI!Guineration用AI打造用户专属动态界面
  • 第六届电子通讯与人工智能国际学术会议(ICECAI 2025)
  • 【C/C++】C++并发编程:std::async与std::thread深度对比