![](https://img-blog.csdnimg.cn/20201014180756757.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C/C++技巧
FlushHip
凝视深渊
展开
-
C++小技巧之反转字符串
下面的代码你一定可以轻松写出:std::string strA = "FlushHip";std::string strB(strA);std::reverse(strB.begin(), strB.end());std::cout << strA << " <-> " << strB << std::endl;有一个小技巧可以少写一行代码:利用反向迭代器和字符串的构造函数。std::string strA = "FlushHip"原创 2022-03-08 14:49:19 · 2095 阅读 · 0 评论 -
聊聊C++标准库,准标准库中关于时间的概念和用法
概要在实际C++业务开发中,经常需要使用系统API或者标准库去获取时间,计算时间的需求,其中,时间按概念又分时间段,时间点;按表达形式又分系统时间,本地时间;其实,获取到了时间,如何通过日志的方式把时间恰当表现出来。而我这边使用Windows下开发较多,因此,这里主要介绍Windows和标准库及Boost准标准库关于时间的相关概念和用法。标准库打开标准库关于时间的命名空间chrono https://en.cppreference.com/w/cpp/chrono可以看到三个概念:clock原创 2020-07-23 13:20:31 · 1681 阅读 · 0 评论 -
C++中操控器Manipulator控制IO格式浅析
背景对于从C语言过渡到C++的筒子来说,输出流的格式控制是个头痛的事,printf的字符串格式控制不香吗?确实香,很多C++的开源类库都实现了printf的格式控制,函数签名大概类似Format(const std::string &, ...),甚至其他语言都借鉴了printf这种格式控制方式。而C++的输入输出是基于流的方式,类似于std::cout << "Flush...原创 2020-02-26 12:46:21 · 1038 阅读 · 1 评论 -
C++中std::string与C-String字符数组的互相转换
C语言中只有字符数组这一说法,没有C++专门封装的字符串类std::string。而字符数组C-String以\0作为结束符。std::string其实还是存储了C-String这个指针,只不过不同的编译期对std::string中的存储结构都做了不同的处理,这里我们不讨论std::string的实现,只关心一件事,那就是C-String和std::string的相互转换。C-String 2 ...原创 2018-11-27 14:30:00 · 8188 阅读 · 0 评论 -
C++中实现HMAC单向散列类
HMAC的维基百科解释是:hash-based message authentication code,其实就是加了盐的单向散列算法。而HMAC的重点就是如何给要散列的数据加盐。加盐公式如下:解释一下上面的符号:⊕\oplus⊕表示异或运算;mmm表示要散列的数据;a∣∣ba || ba∣∣b表示把aaa加入bbb,其实就是用散列算法把aaa算一下,紧接着把bbb算一下;ipadi...原创 2018-12-05 14:34:28 · 2115 阅读 · 0 评论 -
Windows/Linux下C++对于UUID的跨平台封装
Universally Unique Identifier,UUID,通用唯一识别码。是用于计算机体系中以识别信息数目的一个128位标识符,这个东西很有用,在分布式系统中经常用于标识一个结点。根据标准方法生成,不依赖中央机构的注册和分配,UUID具有唯一性,这与其他大多数编号方案不同。重复UUID码概率接近零,可以忽略不计。UUID是128位,16个字节,可以用32个HEX进制的数字表示。标准的...原创 2018-12-19 16:29:28 · 5654 阅读 · 1 评论 -
Windows下C++程序实现单例运行
在Windows下,有些程序是需要单例运行的,比如QQ和Wechat吧。QQ可以打开多个Wechat只能打开一个可以自己在Windows下点一点就知道了。那么在Windows下如何实现单例运行呢?这个单例运行和代码的单例设计模式是不是一个东西呢?一一来回答。首先单例模式和这个肯定是不一样的,单例设计模式解决的是在一个进程中只能有一个类实例问题;而程序单例运行是值系统中只能运行该程序的...原创 2018-12-17 19:36:38 · 2513 阅读 · 0 评论 -
聊聊C++11标准库中堆(heap)算法的源码
STL中支持堆操作,对外暴露了`std::make_heap`,`std::push_heap`,`std::pop_heap`,`std::sort_heap`,`std::is_heap`,`std::is_heap_until`这6个函数,详细的使用方法可以参见[图解STL中算法的分类、简介及其Demo](https://blog.csdn.net/FlushHip/article/details/82858933#t37)。原创 2018-12-29 16:25:21 · 1993 阅读 · 2 评论 -
聊聊C++标准库中优先队列priority_queue的源码
C++标准库提供了优先队列priority_queue,顾名思义,就是可以按照优先级出队的队列,而且时间复杂度为O(logn)O(logn)O(logn),算法中有很多优化项就是用优先队列来优化的。C++11的标准库是怎么构造出优先队列的呢?优先队列是用堆来构造的。所以,优先队列其实并不能叫队列,它的完整定义应该是这样的:优先队列是用堆来构造,包装成队列的适配器。其实想一想,堆确实适合构造优先...原创 2019-01-02 20:47:33 · 1903 阅读 · 0 评论 -
利用googletest命令行参数简化单元测试
首先看看gtest如何写:#include <gtest/gtest.h>int main(int argc, char **argv){ testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS();}TEST(main, minor){}可以看到,main中的命令行参数传入了g...原创 2019-02-26 18:05:35 · 9299 阅读 · 0 评论 -
从一道多线程题来看C++11中条件变量std::condition_variable的使用和原理
现在有一道笔试题是下面这样子的。有两个线程,一个线程循环输出A,另一个线程循环输出B,如何让这两个线程在控制台稳定输出ABABAB…。不用思考太多,我们肯定会定义一个标志变量isTurnA,isTurnA为true输出A,同理输出B,这是一种最简单的有限状态机,只要按照这个状态机进行,那么肯定能答应出答案。isTurnA是共享数据,因此用原子变量或者互斥锁来保护,这里用互斥锁std::mu...原创 2019-03-07 17:26:01 · 784 阅读 · 0 评论 -
C++实现URL的UTF8转码
urlurlurl不能出现中文,导致不能传输中文数据,解决方法有下面两个:统一使用base64base64base64转换一下;把中文用UTF-8存储,然后对其进行可视化编码,这也是浏览器的做法。先来看下,一条urlurlurl在浏览器中会被转化成什么样,可以用在线的网址转一下。before :https://blog.csdn.net/FlushHip?type=1&nam...原创 2019-03-15 17:11:26 · 2707 阅读 · 3 评论 -
线段树浅析及其指针式C/C++写法
hihocoder 19 - 22线段树节点的数据结构typedef struct Node { int data; Node *lchs, *rchs; Node (int data = 0, Node *lchs = nullptr, Node *rchs = nullptr) : data(data), lchs(lchs), rchs(r...原创 2019-04-23 16:33:40 · 884 阅读 · 0 评论 -
聊聊实现C++跨平台ping函数及ICMP请求回显数据包解析
ping我们经常使用,大多数的时候是在命令行ping下IP地址,然后一堆输出。程序中有时候也会用ping函数,那么ping是如何实现的呢。计算机网络告诉我们,ping函数是基于ICMP协议实现的,而ICMP协议又是基于IP协议弄的(ICMP作为IP协议的数据部分传输)。ping通过ICMP协议中的类型8和代码0来搞的,这个类型和代码的组合在ICMP协议中表示请求回显。如果能正常回显,那么返回...原创 2018-11-12 17:26:59 · 3391 阅读 · 4 评论 -
聊聊C++跨类通信机制之消息总线及其实现
如果没有怎么写过项目,更确切地说是没有用面向对象的语言写过项目。就不会明白跨类通信这个需求是多么刚需。为什么要跨类通信?把所有的逻辑都写在一个类中,都是一家人,那就不需要通信了啊。是,确实是这样,当功能不是很多的时候,这样做确实好。但是,随着项目的规模增大,各种功能堆积,各种模块的增加,会使得这个类非常臃肿与庞大。臃肿庞大就意味着不好维护和扩展。因此,我们需要把功能划分出来,把模块划分得细一些...原创 2018-11-06 18:02:53 · 4152 阅读 · 3 评论 -
浅析C++类的作用域
明确一点,一个类就是一个独立的作用域,这也是为什么在类外定义函数或静态变量需要加上类名和作用域符号(类似void Complex::get() {})。如果不加,那么这个get函数默认就是定义在全局范围中,如果你在类中使用了get函数,那么编译器看到Complex::get()没有被定义,从而会调用::get()。这样破坏了类的封装性,同时,如果get中使用了Complex类中的成员变量还会报错。...原创 2018-05-14 22:23:55 · 8969 阅读 · 0 评论 -
C/C++中".."[expression]的解释与妙用
写这篇博客的原因是因为三个月前看到别人的代码中有这么一段:for (int i = 0; i &amp;amp;amp;lt; 100; ++i) printf(&amp;amp;quot;%d%c&amp;amp;quot;, i, &amp;amp;quot; \n&amp;amp;quot;[i == 100 - 1]);这段代码的作用就是下面代码的作用:for (int i = 0; i &a原创 2018-07-27 16:57:22 · 4362 阅读 · 0 评论 -
C++11线程库std::thread中提取线程id
C++有了支持多线程的thread库,只需要包含头文件#include &lt;thread&gt;就能使用,那么如何获取一个线程的id呢?thread中提供了std::thread::get_id()这个方法,这个方法返回的是_M_id,类型是std::thread::id: private: id _M_id; thread::id ...原创 2018-08-21 10:39:29 · 37528 阅读 · 8 评论 -
Base64编解码及其C++实现
这两天在为公司的框架添加一个Base64加解密的模块,于是就想分享一下Base64的原理及自己的C++实现,借鉴了poco库。博文中的代码都是这两天写的代码的简洁版,可以完成Base64的编解码,方便易用。不推荐造轮子,但是轮子在别的车上,你得自己拆下来,然后根据自己车的尺寸DIY你的轮子,安在自己的车上,当然,你还需要了解这个轮子的原理,万一哪天轮子坏了要你来修呢。Base64简介B...原创 2018-09-07 23:07:13 · 27333 阅读 · 7 评论 -
C++中字符编码的转换(Unicode、UTF-8、ANSI)
C++的项目,字符编码是一个大坑,不同平台之间的编码往往不一样,如果不同编码格式用一套字符读取格式读取就会出现乱码。因此,一般都是转化成UTF-8这种平台通用,且支持性很好的编码格式。Unicode、UTF-8的概念不做过多解释,这里说一下ANSI,我第一次看到这个名词,我看成了ASCII。被Mentor狠批一顿。ANSI是一种字符代码,为使计算机支持更多语言,通常使用 0x00 ~ 0x7...原创 2018-09-25 14:11:09 · 62708 阅读 · 17 评论 -
C++中的事件Event(基于条件变量的封装)
考虑这样一个场景,现在有两条线程,一条线程负责往队列中塞元素,另一条线程负责从队列中取元素。其实就是简单的生产者消费者队列,取元素的这个线程需要注意队列中是否有元素,如果没有元素就不能取,于是我就搞一个循环,一直取看队列是否为空:for( ; !que.empty(); ) {}这样子确实可以实现没有元素就等待,有元素就取元素,但是这样搞,这条形成一直处于CPU100%运行的状态,好像这种情...原创 2018-09-25 18:47:33 · 6550 阅读 · 1 评论 -
C++互斥变量对象的包装(基于C++的特性)
在多线程编程中,对一个对象或者多个对象加锁非常常见(保证临界区的互斥访问),其中std::mutex是用的最多的,用互斥量保持互斥访问。假如有五个需要互斥访问的变量,你就需要定义这五个变量,同时,为它们分别定义五个std::mutex。这样子会很凌乱。那么C++中可以把变量和锁绑定在一起作为一个对象,使得这个对象平时使用起来和变量无异,只不过这个对象带了一把锁。C++的语法特性可以很方便地搞定,...原创 2018-09-26 14:05:10 · 805 阅读 · 1 评论 -
白话跨平台C++线程池实现
线程池在一个C++项目中是必不可少的。去看任何一个C++开发框架,绝大部分都会实现一个线程池。而如今C++11已经成熟,借助C++标准库中的线程库std::thread,以及标准库提供的多线程同步神器std::condition_variable(这个已经被我封装成了Event,详情见C++中的事件Event(基于条件变量的封装))和std::future,互斥变量以及锁std::mutex(这个...原创 2018-09-28 17:59:15 · 1837 阅读 · 9 评论 -
图解STL中算法的分类、简介及其Demo
STL中包含算法头文件&amp;amp;amp;amp;amp;amp;amp;lt;algorithm&amp;amp;amp;amp;amp;amp;amp;gt;就可以使用其中的算法了,使用这些通用的算法可以使得代码更加简单、易读、通用。但是这些算法有哪些呢?以及这些算法的职能又是什么?其实这些东西,候捷大师在他的《STL源码剖析》中都有列举,且FluentCPP有一篇文章105 STL Algorithms in Less Than an Hour,他也给STL的10原创 2018-10-08 16:21:33 · 2694 阅读 · 1 评论 -
C++11中type_traits中的基石 - integral_constant
C++标准库的的编写方法是基于模板元来编程的,既然是用模板,那么就少不了与类型打交道,而C++11标准库中新加入了&amp;lt;type_traits&amp;gt;头文件,这个里面新加入了很多与类型特性有关的模板元,在编译期间这些东西就是利器,非常好用。而打开&amp;lt;type_traits&amp;gt;头文件,看到的第一个模板类就是integral_constant,这个类是type_traits的基石,基本上t...原创 2018-10-10 12:28:40 · 5333 阅读 · 1 评论 -
细说C++11中ratio编译期分数(一)
对于分数,C++的标准库并没有提供这样的一个类,如果需要完全可以自己去实现,但是C++11提供了一个编译期常量分数类std::ratio,这个类定义于&lt;ratio&gt;头文件中。这个类允许你具体指定编译期分数,并允许对它们执行编译期运算(可以化简为最简式),而且,它是编译期安全的,这个在源码中可以看到,类似分母为0这种异常在编译期就能捕获。先来看看如何使用这个std::ratio:t...原创 2018-10-10 14:08:24 · 1018 阅读 · 2 评论 -
聊聊C++任务定时器的设计与具体实现
在项目中,经常会遇到这种场景:在特定的时间点去执行一些任务,这就是定时任务。如何实现定时任务呢?如果不用任何技巧,我们可以把当前线程睡一睡,睡到特定的时间点再起来执行特定任务。看起来是解决了这个问题,但是,如果在睡一睡的这个过程,我还想执行一些其他的任务,怎么办?好像也可以解决,开一条新的线程去睡;如果在睡的过程中我不想再执行这个任务了,怎么办,直接中断线程?C++11没有这个机制,虽然这个机制...原创 2018-11-03 22:29:10 · 8968 阅读 · 11 评论 -
C/C++中的do-while循环的妙用
最近在公司实习,看后台服务器的代码比较多,见识了很多东西的妙用,比如说do-while循环的用法。关于do-while与while,for的区别我就不多说了,其中要明确的一点是do-while循环是一定会执行一遍循环体。利用do-while循环是一定会执行一遍循环体的这个特点,可以完成两个功能:封装代码块、提供代码块入出口。下面细细来说。封装代码块这个东西主要体现在宏定义中,如果你...原创 2018-03-01 10:30:46 · 4531 阅读 · 4 评论