C/C++
文章平均质量分 90
HerofH_
加油啊咸鱼!
展开
-
STL源码分析:浅析string和vector<char>的区别
目录前言转换为C-style字符串重载输入输出流操作符重载+、+=操作符前言 为什么会关注string和vector<char>的区别? 先来说下string这个“类”。 string和vector、list、deque等容器不一样,在STL中并不存在class string{...},它实际上是一个全局类型,通过typed...原创 2019-10-24 11:57:13 · 2911 阅读 · 0 评论 -
STL源码分析:sort函数
目录支持sort的容器几种涉及到的排序算法插入排序快速排序堆排序sort函数的策略sort函数的实现STL的sort函数非常常用,不同的STL版本有不同的实现方式,本文就来说一下SGI STL中是如何实现sort函数的。 sort函数所采用的排序方法并非是“一种”,而是“多种”排序算法的“混合物”。在SGI STL的版本中,对一个序...原创 2019-10-10 23:07:51 · 872 阅读 · 0 评论 -
STL源码分析:浅析list的sort函数
目录原理说明举例说明总结 虽然STL中提供了标准的sort函数,但是它只适用于随机存取的容器,而显然list并不是这样的容器,因此list提供了专用的链表排序函数,虽然同样名为sort,但是这个sort函数是list类的成员函数。 在分析list的sort函数之前,有必要先简单了解一下list其它几个相关的成员函数。swap函数:传入参数为一个li...原创 2019-10-07 22:01:54 · 851 阅读 · 0 评论 -
STL源码分析:空间配置器浅析
目录allocatoralloc一级配置器二级配置器自由链表内存分配allocate_S_refill函数_S_chunk_alloc函数内存释放deallocate为什么要使用free_list?为什么free_list要把128bytes分成16部分?对于一些容器如vector、map、set之类的,都需要一个模板参数Alloc...原创 2019-09-27 17:07:47 · 605 阅读 · 0 评论 -
从源码理解智能指针(二)—— shared_ptr、weak_ptr
目录计数器_Ref_count_Ref_count_del_Ref_count_del_alloc_Ptr_base_Ptr_base的成员变量构造函数赋值重载获取引用计数减少引用计数_Reset函数_Resetw函数shared_ptr构造函数无参构造用一般参数构造用完整对象构造移动构造析构函数赋值重载reset...原创 2019-09-24 09:53:37 · 11679 阅读 · 4 评论 -
C++11中的模板特例化
目录函数模板特例化类模板特例化 最近在看智能指针的源码,发现其中用了很多模板特例化,本文就来总结一下,什么是模板特例化。 特例化,顾名思义:特殊实例化,将函数模板或类模板实例化为特殊的类型,通过模板特例化可以定制在特定模板参数下的函数模板/类模板实现,或者禁用特定模板的函数模板/类模板。函数模板特例化 既然是特例化,那么自然就需要有一个“原型”,现在...原创 2019-09-22 09:22:23 · 1563 阅读 · 0 评论 -
从源码理解智能指针(一)——auto_ptr、unique_ptr
目录auto_ptr构造函数拷贝赋值让auto_ptr对象具有指针的行为析构函数unique_ptr_Unique_ptr_baseremove_reference_Get_deleter_pointer_type_Unique_ptr_base的第三个模板参数构造函数无参/NULL构造用管理对象实例构造用管理对象实例及删除器实例构造用另...原创 2019-09-20 16:05:35 · 1509 阅读 · 1 评论 -
从反汇编理解指针和引用的区别
目录初始化赋值取地址总结本文主要基于反汇编代码,从初始化、赋值以及取地址三个角度来理解指针和引用的区别。初始化 写出以下代码并查看反汇编代码:int main(){ int x = 5; int * ptr = &x; //指针 int & ref = x; //引用 return 0;}...原创 2019-09-05 19:54:07 · 588 阅读 · 1 评论 -
模板函数——后置返回值类型(trailing return type)
后置返回值类型主要用于模板函数中,它是C++11推出的新用法。其中使用到了auto和decltype两种类型说明符。 auto和decltype虽然都是类型说明符,但是二者是不同的:auto是根据推导初始值的类型来确定变量的类型,而decltype则只是确定类型,如下所示:auto i = x + y; //通过x+y的结果类型来推导出i的类型并对其初始化...原创 2019-09-05 12:58:10 · 3626 阅读 · 0 评论 -
C++中的虚函数表和虚函数在内存中的位置
目录结论 今天在看别人面经的时候发现了这个问题,一时间发现自己也说不清楚,还想当然的以为“虚函数表既然是类对象公有的,那么应该在静态存储区”,想当然终究只是想当然,经过试验得知,这种想法是错误的。 由于不同的编译器在虚函数表上的实现可能不同,下面以g++来进行分析。 先创建一个有虚函数的类A,如下所示:class A{public:...原创 2019-08-01 13:15:21 · 14812 阅读 · 14 评论 -
C/C++:位域、符号扩展
目录位域定义符号扩展位域使用位域值的计算及赋值位域的对齐原则位域定义 什么是位域?用一个简单的例子来说,假如你在类/结构体中定义了一个变量,这个变量的取值只可能是0~3之类的(比如某种标志位),明明只需要用2个二进制位就可以存下来的,结果你必须得至少为其分配1个字节进行存储(比如用char,甚至是int),这样就至少有6个二进制位是毫无作用的,并且由于内存对...原创 2019-07-09 19:11:24 · 1132 阅读 · 0 评论 -
MFC中CListCtrl改变选中行(选中列)的颜色实现选中高亮的效果
在项目中遇到了这样的需求,需要对选中行进行高亮,查了一下相关的资料,记录一下自己采用的方法。 先在List控件所在类中(这里是CListshow,继承于CListCtrl)添加两个变量SelectRow和SelectCol,用于保存鼠标点击的单元格的行数和列数:class CListshow : public CListCtrl{ ...... ...原创 2019-06-27 17:37:26 · 7655 阅读 · 6 评论 -
C++知识积累:继承关系(含虚函数)下类的内存布局
目录1 无继承2 一般继承2.1 单继承2.2 多层继承2.3 多重继承2.4菱形继承3 虚继承3.1 虚继承的布局3.2 虚继承的多层继承3.3 虚继承的菱形继承总结1 无继承 类A定义如下:class A{private: int A_1;public: static int A_2; int A_3; ...原创 2019-06-22 14:21:15 · 1569 阅读 · 10 评论 -
do{...}while(0);的好处
最近阅读libevent源码时,会看到有很多宏定义中使用了do{...}while(0);,看了看一些资料,发现很多源码也会这么写,那么do{...}while(0);的好处是什么呢?这里说一下常见的两种用法:保证宏定义的正确使用 举个例子,如果现在定义如下一个宏:#define FUN \ f1(); \ f2();...原创 2019-05-22 11:22:16 · 1741 阅读 · 0 评论 -
关于MFC中使用ShellExecute出现的进程冲突问题
目录问题背景问题分析问题背景 现在有一个MFC写的界面程序,以及一个外部exe文件。用户通过界面选择文件a,MFC将文件a的路径作为参数,调用exe文件生成一个解析文件b,然后MFC再读取这个文件b。 为了完成这一目的,就需要在MFC中调用外部exe文件,我这里选用的是ShellExecute函数。//function...HINSTANCE ...原创 2019-04-25 22:42:54 · 1397 阅读 · 0 评论 -
C ++ 多线程:条件变量、unique_lock
目录1 前言2 条件变量3 unique_lock1 前言 为了更好的理解条件变量是什么,我们还是应当先思考一下为什么需要条件变量,还是先以一段程序为例:using namespace std;class MsgList //模拟消息的写入和读取{public: void MsgWrite() { for (int i = 0; i <...原创 2019-03-10 21:04:36 · 2713 阅读 · 3 评论 -
C++多线程:互斥锁
目录1.前言2.互斥锁2.1 互斥锁的特点2.2 互斥锁的使用2.2 std::lock_guard3.死锁3.1 死锁的含义3.2 死锁的例子3.3 死锁的解决方法1.前言 比如说我们现在以一个list容器来模仿一个消息队列,当消息来临时插入list的尾部,当读取消息时就把头部的消息读出来并且删除这条消息。在代码中就以两个线程分别实现消息写...原创 2019-03-10 10:32:55 · 31635 阅读 · 13 评论 -
C++多线程:创建线程
C++中线程的创建一般是通过std::thread类实现的,具体的实现方式有以下几种:1 使用函数名创建void pcreat(int a) { cout << "start !" << a << endl;}int main(){ thread p(pcreat,4); //如果函数无参则省略第二个参数,多参数直接加在后面即...原创 2019-03-07 15:43:40 · 1478 阅读 · 0 评论 -
C++知识积累:浅析Lambda表达式
目录1 引言2 如何创建Lambda表达式3 总结Lambda是C++ 11的新特性之一,查看网上对其的解释往往晦涩难懂,在这说下自己的理解。1 引言 我们先来看个排序的例子:bool cmp(const int &a, const int &b) //定义比较函数{ return a > b;}int main(...原创 2019-03-07 15:36:26 · 315 阅读 · 0 评论 -
C++知识积累:构造函数与析构函数是否应为虚函数
目录1 构造函数不能是虚函数2 析构函数应当是虚函数其他需要注意的地方1 构造函数不能是虚函数 构造函数不能声明为虚函数。虚函数是需要通过对象中的虚表指针来找到虚函数表,然后再调用相应虚函数的。如果构造函数是虚函数,说明构造函数也是需要用虚表指针来调用的,但是这样一来就必须要先有虚表指针才行,而虚表指针又是存在于对象中,而对象本身又是需要先通过构造函数...原创 2019-03-05 10:25:57 · 839 阅读 · 0 评论 -
C++知识积累:内存对齐理解
为什么要进行内存对齐? 这是因为CPU的读取总是对齐的。举个例子,假设CPU是32位的,那么CPU每次读取的4字节数据的首地址都是4的倍数,也就是说,内存中数据首地址为4的倍数时,CPU一次操作就可以完成数据读取: 假设有一个int型四字节大小的变量存放在0~3地址单元中,那么CPU只需要读取0~3这32位即可,而如果这个变量存放在2~5地址单元中,那么CPU就需要...原创 2019-03-01 13:10:01 · 178 阅读 · 0 评论 -
C++知识积累:浅拷贝与深拷贝
目录1浅拷贝2深拷贝3赋值1浅拷贝 简单来说,浅拷贝就是原封不动的将源对象所占用的一片内存中的所有数据全部拷贝到目的对象所在的内存中,不管这片内存中存放的是什么,即使源对象中的数据成员包含指针(包括虚表指针),那么也会将该指针变量(实际上就是一个地址)拷贝到目的对象中,如果没有显式定义拷贝构造函数,那么在需要的时候程序会自动调用一个默认的拷贝构造函数,而这个...原创 2019-03-01 11:17:23 · 177 阅读 · 0 评论 -
C++知识积累:如何获取虚函数表以及虚函数地址
如果一个类中存在虚函数的话,那么编译器就会为这个类生成一个虚函数表,这个虚函数表中按照个虚函数的声明顺序存放了各个虚函数的地址,需要注意的是,这个虚函数表并不存在于类中,而对于这个类的每个对象,编译器都会为其生成一个透明不可见的指针,这个指针就是虚函数表指针,位于该对象内存中的开头,并指向了虚函数表的位置。换句话说,如果一个类中存在虚函数,假设声明一个对象a,在32位的编译情况下,对...原创 2019-02-27 22:21:30 · 6120 阅读 · 3 评论 -
C++知识积累:explicit关键字的作用
explicit意为“显式的”,该关键字主要是用于防止类构造函数出现隐式类型转换的情况,且只适用于仅含一个参数的构造函数。 我们先来看第一个问题:什么是防止构造函数出现隐式转换呢?来看下面的例子:class A{public : A(int a) { cout << "Constructor called and param is "&l...原创 2019-02-26 16:52:20 · 629 阅读 · 0 评论 -
sort函数、priority_queue中比较函数的写法
目录1.sort函数中的cmp1.1 重载小于操作符1.2 自定义Cmp函数1.3 自定义仿函数2.priority_queue中的cmp2.1 重载小于操作符2.2 自定义仿函数3. 补充说明1.sort函数中的cmp sort函数的说明如下: 由图中可以看到,sort函数有两种原...原创 2019-01-15 19:30:49 · 5343 阅读 · 5 评论 -
C++知识积累:stringstream使用
< sstream > 定义了三个类:istringstream、ostringstream 和 stringstream,分别用来进行流的输入、输出和输入输出操作。本文以 stringstream 为主,介绍流的输入和输出操作。< sstream > 主要用来进行数据类型转换,由于 < sstream > 使用 string 对象来代替字符数组(snprin...原创 2019-01-04 15:28:04 · 795 阅读 · 0 评论 -
C++知识积累:cin、getline解析
一、string类的getline函数(全局函数)getline(cin,str)函数是处理string类的函数。第二个参数为string类型的变量。读入时第二个参数为string类型,而不是char*,要注意区别getline()函数的定义如下所示1. istream&amp;amp;amp;amp;amp; getline ( istream &amp;amp;amp;amp;amp;is , string &amp;amp;amp;amp;amp;原创 2019-01-04 14:28:21 · 2035 阅读 · 0 评论 -
C++知识积累:重载、隐藏和重写的区别
基本概念:重载:是指同一可访问区内被声明的几个具有不同参数列(参数的类型,个数,顺序不同)的同名函数,根据参数列表确定调用哪个函数,重载不关心函数返回类型。示例:class A{public: void test(int a); void test(double a);//重载 void test(int a, double b);//重载 void test(double...原创 2018-12-24 10:10:49 · 274 阅读 · 0 评论 -
C++知识积累:运算符重载时构造函数与析构函数调用次数不一致的问题
在学习运算符重载的时候自己写了这样一段程序:class Stu{ public: Stu() { std::cout&amp;amp;lt;&amp;amp;lt;&amp;quot;Stu No parameter constructor called!&amp;quot;&amp;amp;lt;&amp;amp;lt;std::endl; } Stu(in原创 2018-11-26 10:45:07 · 1318 阅读 · 0 评论 -
C++知识积累:类继承中构造函数与析构函数的调用顺序问题
先来看单继承的情况,以类A为基类,类B为类A的派生类,试运行以下程序:class A{public: A():age(1),name("ll") { cout<<"Class A Empty Constructor !"<<endl; } A(A &a) { cout<<"Cl...原创 2018-11-20 19:43:19 · 467 阅读 · 0 评论 -
C++知识积累:const修饰符总结
const是特别容易弄混的一点,现在以int和const来说,它的使用方式一般有以下几种:int const、const int 、int const* 、const int*、int * const、const int* const、int const * constint const &、const int &int const 、const intint con...原创 2018-11-15 20:49:37 · 213 阅读 · 0 评论 -
C++知识积累:成员函数运算符重载与非成员函数运算符重载
运算符重载,是C++多态的表现形式之一,可以通过对运算符进行重载来实现运算符特定的功能。运算符重载一般具有以下原则:(1)不可重载不存在的运算符,如重载**来表示平方等;(2)重载后的运算符与原来的运算符优先级、结合性以及操作数数目相同,如双目运算符不能重载为单目;(3)保留运算符本身的含义,如“+”号重载后应该保持其“求和”的自然含义;(4)操作数中至少有一个为自定义类型,如重载运算符...原创 2018-11-15 14:48:49 · 10011 阅读 · 2 评论