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

让网站不要保存密码怎么做百度助手app下载安装

让网站不要保存密码怎么做,百度助手app下载安装,手机兼职项目,qq恢复官方网站author: hjjdebug date: 2025年 05月 21日 星期三 15:48:00 CST descrip: chrono类 根据duration 类的周期类型得到对应的周期名称 文章目录 1. 测试代码:2.条件编译代码:3. main 函数的汇编码.4. check_unit_ratio\<std::chrono:duration>long,std::ratio<1l,1l>&…

author: hjjdebug
date: 2025年 05月 21日 星期三 15:48:00 CST
descrip: chrono类 根据duration 类的周期类型得到对应的周期名称


文章目录

  • 1. 测试代码:
  • 2.条件编译代码:
  • 3. main 函数的汇编码.
  • 4. check_unit_ratio\<std::chrono:duration>long,std::ratio<1l,1l>> 函数
  • 5. get_unit_name\<T> 对应的一个函数
  • 5. 小结:

目的:

  1. 熟悉 chrono 定时类的用法,
  2. 熟悉模板函数的写法.
  3. 熟悉运行函数及编译函数的混合用法

c++与gcc 的交互显得越来越多了. 用多了就熟悉了.

1. 测试代码:

$ cat main.cpp
//chrono类 根据duration 类的周期类型得到对应的周期名称
// 不知道标准库里是否有对应函数, 自己写一下吧, 练练手.还可扩展功能.
#include <iostream>
#include <chrono>
#include <string_view>
//功能: 编译期函数, 获取duration 的类型名称, 
//根据传来的数据类型,返回自编的类型名称
//Period, 是模板类型参数, 类型是可变的.
//string_view 字符串视图,不持有字符串数据,仅是对字符串的引用,无数据copy,内存开销极低. 
//虽然它描述的很好, 但也不及指针来得更轻巧! string_view既然做为类出现,会提供一些常用的方法.template <typename Period>
constexpr std::string_view get_unit_name()  {using namespace std; // 指定现在使用std 命名空间//用if constexpr, 可以简小函数的尺寸,根据表达式,生成或不生成代码,类似于#ifdef #endif,但判断标准是编译期变量的值//is_same_v<T,U> 是编译期函数, 在生成的代码中是看不到的,被gcc 优化掉了. if constexpr (is_same_v<Period, ratio<1, 1>>)return "seconds";else if constexpr (is_same_v<Period, milli>) return "milliseconds";else if constexpr (is_same_v<Period, micro>)return "microseconds";else if constexpr (is_same_v<Period, nano>)return "nanoseconds";else if constexpr (is_same_v<Period, ratio<60, 1>>)return "minutes";else if constexpr (is_same_v<Period, ratio<3600, 1>>)return "hours";elsereturn "custom unit";
}// Unit, 模板类型参数template <typename Unit>
void check_unit_ratio() 
{if constexpr (std::is_integral_v<Unit>)  //传来的类型不能是整数,由于本测试其为假,所以该代码块不会出现在执行代码中.{std::cout << "You should Use Duration Type, not int type!"<<"\n";return;}using Period = typename Unit::period; //模板类型必需要有period类型, duration 的period 是分数模板类型.std::cout << "Duration unit: " << get_unit_name<Period>() << "\n"; //由于该调用,会生成一堆get_unit_name<...>函数std::cout << "Numerator: " << Period::num << "\n";std::cout << "Denominator: " << Period::den << "\n";
}//自建一个测试类型
class MyClass
{
};
int main() {using namespace std::chrono;// 预定义数据类型单位检测,seconds,milliseconds,milliseconds 都是chrono中预先定义的类型check_unit_ratio<seconds>(); //由于该调用,会为它生成check_unit_ratio<seconds> 函数check_unit_ratio<milliseconds>(); //由于该调用,会为它生成check_unit_ratio<milliseconds> 函数check_unit_ratio<microseconds>(); //由于该调用,会为它生成check_unit_ratio<microseconds> 函数// 自定义单位检测(例如:定义一个100毫秒的类型0.1)using MyDuration = duration<int, std::ratio<1, 10>>; // 0.1秒check_unit_ratio<MyDuration>(); //由于该调用,会为它生成check_unit_ratio<MyDuration> 函数// 随便给个类型,它肯定干不了, 因为它不能实例化指定的模板函数, 例如下面的代码// main.cpp:37:11: error: ‘double’ is not a class, struct, or union type// 37 |     using Period = typename Unit::period; //模板类型必需要有period类型, period类型是后续要处理的类型//	check_unit_ratio<double>();//main.cpp|37 col 11| error: no type named ‘period’ in ‘class MyClass’//    37 |     using Period = typename Unit::period; //模板类型必需要有period类型, period类型是后续要处理的类型//	check_unit_ratio<MyClass>();
}

执行结果:
$ ./temp2
Duration unit: seconds
Numerator: 1
Denominator: 1
Duration unit: milliseconds
Numerator: 1
Denominator: 1000
Duration unit: microseconds
Numerator: 1
Denominator: 1000000
Duration unit: custom unit
Numerator: 1
Denominator: 10

2.条件编译代码:

if constexpr在编译时评估表达式,并根据结果选择要编译的代码路径。
只有当条件表达式为真时,相应的代码块才会被编译,其他分支的代码则不会被生成.
下面函数是可以和if constexpr 配合的编译期函数
std::is_integral_v
std::is_floating_point_v
std::is_same_v<T,U>

这些是编译期函数,其结果是true或false, 可控制代码编译.

想搞清主代码的执行框架, 看清gcc做了哪些工作.还是要结合看汇编代码了.

3. main 函数的汇编码.

例如: main 函数, 可以看到, 它调用了很多函数. 意味着,模板函数 check_unit_ratio() 生成了很多函数.

int main() {4011d6:	f3 0f 1e fa          	endbr64 4011da:	55                   	push   %rbp4011db:	48 89 e5             	mov    %rsp,%rbpusing namespace std::chrono;// 预定义数据类型单位检测,seconds,milliseconds,milliseconds 都是chrono中预先定义的类型check_unit_ratio<seconds>(); //由于该调用,会为它生成check_unit_ratio<seconds> 函数4011de:	e8 79 01 00 00       	callq  40135c <void check_unit_ratio<std::chrono::duration<long, std::ratio<1l, 1l> > >()>check_unit_ratio<milliseconds>(); //由于该调用,会为它生成check_unit_ratio<milliseconds> 函数4011e3:	e8 2d 02 00 00       	callq  401415 <void check_unit_ratio<std::chrono::duration<long, std::ratio<1l, 1000l> > >()>check_unit_ratio<microseconds>(); //由于该调用,会为它生成check_unit_ratio<microseconds> 函数4011e8:	e8 e1 02 00 00       	callq  4014ce <void check_unit_ratio<std::chrono::duration<long, std::ratio<1l, 1000000l> > >()>// 自定义单位检测(例如:定义一个100毫秒的类型0.1)using MyDuration = duration<int, std::ratio<1, 10>>; // 0.1秒check_unit_ratio<MyDuration>(); //由于该调用,会为它生成check_unit_ratio<MyDuration> 函数4011ed:	e8 95 03 00 00       	callq  401587 <void check_unit_ratio<std::chrono::duration<int, std::ratio<1l, 10l> > >()>// 37 |     using Period = typename Unit::period; //模板类型必需要有period类型, period类型是后续要处理的类型
//	check_unit_ratio<double>();
//main.cpp|37 col 11| error: no type named ‘period’ in ‘class MyClass’
//    37 |     using Period = typename Unit::period; //模板类型必需要有period类型, period类型是后续要处理的类型
//	check_unit_ratio<MyClass>();
}

check_unit_ratio<type>() 会变成对应一堆函数,
而using MyDuration = duration<int ,std::ratio<1,10>> 则不对应任何代码, 它只是一个类型说明.
跟入一个check_unit_ratio<type>, 例如 40135c, 其它的类似,有可比性.

4. check_unit_ratio<std::chrono:duration>long,std::ratio<1l,1l>> 函数

000000000040135c <void check_unit_ratio<std::chrono::duration<long, std::ratio<1l, 1l> > >()>:
void check_unit_ratio() 40135c:	f3 0f 1e fa          	endbr64 401360:	55                   	push   %rbp       //保留rbp,401361:	48 89 e5             	mov    %rsp,%rbp401364:	41 54                	push   %r12    //保留r12, rbx401366:	53                   	push   %rbxstd::cout << "Duration unit: " << get_unit_name<Period>() << "\n"; //由于该调用,会生成一堆get_unit_name<...>函数401367:	48 8d 35 96 0c 00 00 	lea    0xc96(%rip),%rsi        #   //字符串 “Duration unit:", 第2参数40136e:	48 8b 05 6b 2c 00 00 	mov    0x2c6b(%rip),%rax       401375:	48 89 c7             	mov    %rax,%rdi  //cout this 对象指针,第1参数//调用 << 运算符, <<符有多态性.401378:	e8 23 fd ff ff       	callq  4010a0 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)@plt>40137d:	49 89 c4             	mov    %rax,%r12 , 保留返回值//调用get_unit_name<T> 函数, 返回string401380:	e8 bb 02 00 00       	callq  401640 <std::basic_string_view<char, std::char_traits<char> > get_unit_name<std::ratio<1l, 1l> >()>401385:	48 89 c1             	mov    %rax,%rcx  //返回值保留401388:	48 89 d3             	mov    %rdx,%rbx40138b:	48 89 d0             	mov    %rdx,%rax40138e:	48 89 ce             	mov    %rcx,%rsi  //返回值给第2参数401391:	48 89 c2             	mov    %rax,%rdx401394:	4c 89 e7             	mov    %r12,%rdi  //第1参数//调用 << 运算符401397:	e8 05 03 00 00       	callq  4016a1 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::basic_string_view<char, std::char_traits<char> >)>40139c:	48 8d 35 71 0c 00 00 	lea    0xc71(%rip),%rsi        # endl 给第2参数4013a3:	48 89 c7             	mov    %rax,%rdi    //返回值给第1参数//调用 << 运算符4013a6:	e8 f5 fc ff ff       	callq  4010a0 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)@plt>std::cout << "Numerator: " << Period::num << "\n";4013ab:	48 8d 35 64 0c 00 00 	lea    0xc64(%rip),%rsi        # 402016,2参数 "Numerator:" 字符串 4013b2:	48 8b 05 27 2c 00 00 	mov    0x2c27(%rip),%rax        # 403fe0 第1参数 std::cout 对象地址4013b9:	48 89 c7             	mov    %rax,%rdi//调用 << 运算符4013bc:	e8 df fc ff ff       	callq  4010a0 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)@plt>4013c1:	be 01 00 00 00       	mov    $0x1,%esi       # 第2参数, Period::num 为常数14013c6:	48 89 c7             	mov    %rax,%rdi       # 返回值给第1参数//调用 << 运算符4013c9:	e8 12 fd ff ff       	callq  4010e0 <std::basic_ostream<char, std::char_traits<char> >::operator<<(long)@plt>4013ce:	48 8d 35 3f 0c 00 00 	lea    0xc3f(%rip),%rsi        # 402014 "\n"字符串4013d5:	48 89 c7             	mov    %rax,%rdi         # 返回值//调用 << 运算符4013d8:	e8 c3 fc ff ff       	callq  4010a0 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)@plt>.... //其它忽略了!40140f:	90                   	nop401410:	5b                   	pop    %rbx # 恢复现场, 返回401411:	41 5c                	pop    %r12401413:	5d                   	pop    %rbp401414:	c3                   	retq   

5. get_unit_name<T> 对应的一个函数

分析一个get_unit_name<T> 函数, 例如:401640, 实际返回的是 “seconds” 字符串的string_view视图

0000000000401640 <std::basic_string_view<char, std::char_traits<char> > get_unit_name<std::ratio<1l, 1l> >()>:
constexpr std::string_view get_unit_name()  //string_view 字符串视图,不持有字符串数据,仅是对字符串的引用,无数据copy,内存开销极低. 401640:	f3 0f 1e fa          	endbr64 401644:	55                   	push   %rbp       //保留rbp401645:	48 89 e5             	mov    %rsp,%rbp  //调整栈帧 401648:	48 83 ec 20          	sub    $0x20,%rsp  //开辟局部变量空间40164c:	64 48 8b 04 25 28 00 	mov    %fs:0x28,%rax401653:	00 00 401655:	48 89 45 f8          	mov    %rax,-0x8(%rbp) //保留%0xfs:0x28到局部变量401659:	31 c0                	xor    %eax,%eaxreturn "seconds";40165b:	48 8d 45 e0          	lea    -0x20(%rbp),%rax40165f:	48 8d 35 ca 09 00 00 	lea    0x9ca(%rip),%rsi        # 402030 字符串seconds 地址401666:	48 89 c7             	mov    %rax,%rdi    //this 指针,局部变量地址# 调用std::string_view 的构造函数401669:	e8 74 01 00 00       	callq  4017e2 <std::basic_string_view<char, std::char_traits<char> >::basic_string_view(char const*)>40166e:	48 8b 45 e0          	mov    -0x20(%rbp),%rax , 把局部变量-0x20(%rbp)内容送返回值401672:	48 8b 55 e8          	mov    -0x18(%rbp),%rdx
}401676:	48 8b 4d f8          	mov    -0x8(%rbp),%rcx40167a:	64 48 33 0c 25 28 00 	xor    %fs:0x28,%rcx  %fs:-x28 与局部变量-0x8(%rbp)相异或应该为0401681:	00 00 # 安全判别,0正常则退出401683:	74 05                	je     40168a <std::basic_string_view<char, std::char_traits<char> > get_unit_name<std::ratio<1l, 1l> >()+0x4a>401685:	e8 26 fa ff ff       	callq  4010b0 <__stack_chk_fail@plt> //堆栈被破环40168a:	c9                   	leaveq 40168b:	c3                   	retq   

5. 小结:

类模板会生成很多类. 函数模板会生成很多函数. 模板以类型为参数生成类,生成函数, 这是c++的静态多态
其最终的函数名称由"基本名+参数类型确定"
c++的静态多态还有另一种表现形式,同一作用域下多个同名函数,但参数不同.
其最终名称还是由"基本名+参数类型确定".这种类型估计大家都熟悉了.

http://www.dtcms.com/wzjs/283646.html

相关文章:

  • 天津 论坛网站制作公司seo搜索引擎优化知乎
  • 网站前端语言武汉网络推广广告公司
  • wordpress怎么导入xmlseo销售好做吗
  • 宿迁做网站的公司站长网
  • 福州专业网站建设武汉网络推广自然排名
  • 安徽网站建站系统平台上海最大的seo公司
  • 资源网站推荐宁波建站模板系统
  • 海口可信的海南网站建设seo优化便宜
  • 网站怎么做登陆商务网站如何推广
  • 网上商城排名seo推广网络
  • php动态网站设计作业成品吉林网络公司
  • 网站建设的工作流程百度一下浏览器下载安装
  • 黄埔网站建设优化seo网站页面排名优化
  • wordpress主题在哪个文件夹seo优化排名是什么
  • 做微秀的网站推广网页怎么做的
  • 网站开发合作合同范本百度风云榜各年度小说排行榜
  • 网站备案 法人代表免费网站在线客服软件
  • 在线做视频的网站培训心得体会2000字
  • 烟台网站建设seo在哪里推广自己的产品
  • 做网站需要会什么条件账户竞价托管公司
  • 增城有什么网站做招聘的优化师是做什么的
  • 网站做友链亚马逊关键词快速优化
  • 淄博网站建设公司模板免费下载网站
  • 重庆百度竞价排名seo外包收费
  • 哪里有做网站的怎样做网络销售平台
  • 网站怎么做电子合同网站seo综合诊断
  • 昆明做网站建设的公司排名百度知道个人中心
  • 微信小程序可以做音乐网站吗百度搜索网址大全
  • 太原网站开发团队seo全称英文怎么说
  • 用网站源码怎么做网站目前搜索引擎排名