cpp加油站
文章平均质量分 85
愿桃李开满园,愿春风送天下,本专栏致力于分享c++相关知识,给你,也给我的c++加加油,同名公众号:cpp加油站
cpp加油站
公众号:cpp加油站,专注分享linux下cpp知识
展开
-
【STL源码拆解】基于源码分析forward_lsit容器实现(详细!)
本篇文章介绍一下c++11中新增的顺序容器forward_list,基于stl的源码分析一下该容器的整体实现及数据结构。说明一下,我用的是gcc7.1.0编译器,标准库源代码也是这个版本的。按照惯例,还是先看一下本文大纲,如下:1. forward_list是什么forward_list是c++11为STL新增加的一种顺序容器,使用的时候包含头文件forward_list即可,真实的类声明位于头文件bits/forward_list.h中,类forward_list是一个类模板,基于单链表结构原创 2021-08-09 09:45:42 · 371 阅读 · 4 评论 -
c++11增加的变参数模板,今天总算整明白了
本篇文章介绍一下c++11中增加的变参数模板template<typename... _Args>到底是咋回事,以及它的具体用法。说明一下,我用的是gcc7.1.0编译器,标准库源代码也是这个版本的。按照惯例,还是先看一下本文大纲,如下:在之前写vector和deque容器源码剖析的过程中,经常发现这样的代码,如下:template<typename... _Args>void emplace_front(_Args&&... __args);可以原创 2021-07-29 09:43:47 · 1454 阅读 · 5 评论 -
【deque容器系列二】基于STL源码分析deque容器插入和删除时内存都是怎么变动的
上篇文章我们介绍了deque容器整体结构和构造实现,链接如下:基于STL源码分析deque容器整体实现及内存结构本篇文章接上篇,继续基于gcc中stl的源码剖析deque容器插入、删除、取值的实现原理,以提问者的角度去深入分析这些操作过程中发生了什么,并对deque容器适合使用的场景和使用时的注意事项进行说明。说明一下,我用的是gcc7.1.0编译器,标准库源代码也是这个版本的。按照惯例,还是先看一下本文大纲,如下:0. deque容器迭代器说明在正式开始讲述插入、删除等操作的实现前,我们原创 2021-07-16 12:32:10 · 425 阅读 · 24 评论 -
【deque容器系列一】基于STL源码分析deque容器整体实现及内存结构
本篇文章基于gcc中stl的源码介绍deque容器的整体实现和它的内存结构。说明一下,我用的是gcc7.1.0编译器,标准库源代码也是这个版本的。首先呢,还是看一下思维导图,如下:1. deque容器整体源码实现介绍deque容器是stl中顺序容器的一种,之前已经介绍过array和vector了,今天介绍deque容器,deque的本质是一个类模板,它的声明位于头文件bits/stl_deque.h,实现位于bits/deque.tcc,接下来我们就围绕这两个文件来介绍一下deque容器的实现原创 2021-07-14 11:37:00 · 339 阅读 · 8 评论 -
从c++标准库指针萃取器谈一下traits技法
本篇文章基于gcc中标准库源码剖析一下标准库中的模板类pointer_traits,并且以此为例理解一下traits技法。说明一下,我用的是gcc7.1.0编译器,标准库源代码也是这个版本的。还是先看一下思维导图,如下:1. 指针萃取器pointer_traits说明首先说明一下哈,官方并没有指针萃取器这个名称,其实pointer_traits是类模板,它是c++11以后引入的,可以通过传入的重绑定模板类型得到相应的指针类型,比较官方的描述是:pointer_traits 类模板提供标准化方法原创 2021-07-12 11:07:16 · 495 阅读 · 28 评论 -
【工欲善其事,必先利其器】之gdb五大高级用法
本篇文章讲解gdb的一些高级用法,在我们的开发生涯中,调试是很重要的技能,而在linux下开发,最常用的调试工具就是gdb了,所以这里介绍几种gdb比较高级的用法,助力我们的调试技能。还是先看下思维导图:1. gdb怎么调试多线程gdb调试多线程时,默认情况下是所有线程同时都在执行,但是假设我们想只有一个线程继续执行,其他线程都暂停呢?下面就来看一看该怎么实现这个功能。有这么一段多线程代码,如下://test.cpp#include <stdio.h>#include <p原创 2021-07-06 10:25:48 · 919 阅读 · 15 评论 -
【工欲善其事,必先利其器】之怎么查看c++代码生成的汇编代码
本篇文章讲解怎么得到c++代码对应的汇编代码,想要真正的理解一段代码到底是怎么执行的,还是要从汇编的层面去看,那怎么得到一段c++代码所对应的汇编代码呢,下面为你介绍三种方式。1. gcc编译生成XXX.s文件一般来讲,给你一个cpp文件,比如test.cpp,然后我们编译都是直接g++ test.cpp这样简单直接的方式,但其实它中间有很多个过程的,包含预处理、编译、链接等过程,而这其中的编译这个过程其实就是生成了汇编文件。比如对于一个cpp文件,我们执行下列命令:g++ -E test.cpp原创 2021-07-01 09:32:38 · 362 阅读 · 14 评论 -
上次说了静态数组可变长,今天知道原理了
之前发了一篇文章,讲c99变长数组的,链接如下:多年老c++程序员在静态数组这里翻船了发出去以后有了挺多的反馈,因为这并不是一个很难的知识点,所以如果接触过的自然而然是知道,但还真有挺多人表示不知道和不相信这个事,同时我上次也只是简单的说了一下这个事,没有去讲解这个变长静态数组的实现原理,今天补上。先看一下思维导图:1. 变长数组是长度一直可以变的吗变长数组,那么是长度一直可以变的吗,到底什么时候这个长度会确定下来呢?我们先看一下代码,如下:#include <iostream>原创 2021-06-29 09:17:00 · 597 阅读 · 6 评论 -
c++中引用面试点7连问以及引用真的不分配内存吗
本篇文章从面试官的口吻连问7个引用有关的问题,并且从汇编的层面上对引用进行深入分析,让你充分理解引用的概念和原理。首先还是看一下思维导图:1. 引用的背景和概念说到引用,首先要说一下’&'标识符,其实c语言中这个符号只是用来取地址的,并没有引用的概念,直到c++对这个标识符的作用进行了扩充,才有了引用这个概念。所谓引用,其实就是给变量取了一个别名,一个简单的例子如下:int main(){ int a = 2; int &b = a; return 0;}对于这段c原创 2021-06-28 09:25:36 · 1375 阅读 · 19 评论 -
c++类和继承面试点25连问
本篇文章连问面试时经常会遇到的类和继承相关25个问题,看看你能回答出几道题呀。还是先看一下思维导图,如下:1. c++的三大特性是什么c++的三大特性,说白了其实就是面向对象的三大特性,是指:封装、继承、多态,简单说明如下:封装是一种技术,它使类的定义和实现分离,也就是隐藏了实现细节,只留下接口给他人调用,另外封装还有一层意义是它把某种事物具现出属性和方法并形成了一个整体,就像一个人,同时具有身高和身体等等这些,才是完整的人,如果不封装,那这个人就相当于四分五裂了;继承,所谓继承,其实就是真实原创 2021-06-18 19:43:10 · 273 阅读 · 5 评论 -
c++头脑风暴-多态、虚继承、多重继承内存布局
本篇文章深入分析多态、虚继承、多重继承的内存布局以及实现原理。首先还是看一下思维导图:下面根据这个大纲一步一步的进行深入解析。一、没有虚函数时内存布局是怎样的1. 没有虚函数时类的内存布局一个类没有虚函数的时候,其实就是结构体,它的内存布局就是按照成员变量的顺序来的。看如下代码:#include <iostream>using namespace std;class CPeople{ double height; int age; char sex;public:原创 2021-06-17 09:13:55 · 447 阅读 · 0 评论 -
多年老c++程序员在静态数组这里翻船了
事情的起因事情是这样子滴,有一次我在代码评审的时候,发现有同事想使用运行时才能够获取到的值,去改变一个静态数组的元素个数,我当时就很诧异,因为我心里知道这样是不可行的,静态数组的元素个数在编译时就需要是固定不变的,一般只能是常量或者宏定义,否则编译就不能通过。但是当时我提出来以后,把原因说了,包括写出这个代码的人和另外一位同事都没理解,弄得我有点怀疑自己了,难道是我搞错了?我左思右想,最后我写了下面的代码来证实一下:#include <iostream>using namespace原创 2021-06-08 09:34:02 · 408 阅读 · 4 评论 -
三张图带你弄懂stl内存分配器,再也不怕面试官问了
本篇文章基于源码来剖析标准库中内存分配器的实现原理及使用。说明一下,我用的是gcc7.1.0编译器,标准库源代码也是这个版本的。还是来先通过思维导图来看一下本篇文章会从哪些方面来讲解stl中内存分配器和萃取器,如下:其实stl中有关内存申请的操作是包含两个内容的:内存分配器、内存萃取器。一、vector容器中对内存分配器的使用前面的文章中说了,vector容器本质上是个动态数组,它其实就是使用标准库的内存分配器实现的,还是先看一下代码,如下:template<typename _Tp原创 2021-06-04 19:29:18 · 656 阅读 · 0 评论 -
c++中typename、typedef以及using关键字用法
在c++的标准库中,因为类继承关系比较复杂和模板使用比较多的原因,源代码中充斥着typename、typedef和using这三个关键字,所以在继续剖析标准库源码之前,今天就来介绍一下这三个关键字的作用。一、typename关键字typename的第一个作用是用作模板里面,来声明某种类型,比如这样的:template<typename _Tp, typename _Alloc> struct _Vector_base;最开始的时候声明模板形参,也会使用class,但我们都知道c原创 2021-06-03 09:18:23 · 2155 阅读 · 4 评论 -
超详细STL之基于源码剖析vector实现原理及注意事项
本篇文章基于源码来剖析标准模板库中vector容器的实现原理及一些特殊注意事项。说明一下,我用的是gcc7.1.0编译器,标准库源代码也是这个版本的。多年以前面试的时候第一次被问到stl中vector的底层实现,那个时候的我真的很low,根本回答不上来,后来面试回来,在网络上搜索了一些vector底层实现,知道了它的底层是动态数组,但光知道动态数组是不够的,进一步的,动态数组写满了怎么办,它的实现用了c++的什么技术,一些特殊场景下怎么使用vector更有效率等等,这些极少有人讲清楚,今天我基于gc原创 2021-06-02 09:21:45 · 415 阅读 · 0 评论 -
题解5道c++面试题第一期(含解题思路、答案解析和实现代码)
本篇文章送上5道c/c++面试题目,并附上答案、解题思路以及扩展知识。1. 求下面函数的返回值#include <stdio.h>int func(int x){ int iCnt = 0; while(x) { iCnt++; x = x&(x-1); } return iCnt;}int main(){ printf("cnt = %d\n", func(9999)); return 0;}这题问的是函数的返回值,而通过代码我们能看到返回原创 2021-05-28 09:30:54 · 476 阅读 · 2 评论 -
手写strcpy和memcpy代码实现
本篇文章聊一下strcpy和memcpy的代码实现,这两个也是c和c++面试中常考的问题点。1. 手写strcpy首先看一下,一份标准的strcpy的实现如下:char *strcpy(char* strDest, const char* strSrc){ assert( (strDest != NULL) && (strSrc != NULL)); char *address = strDest; while((*strDest++ = *strSrc++) != '\0')原创 2021-05-26 09:28:53 · 460 阅读 · 0 评论 -
c++编码规范
我的c++编码规范:属性 规则 例子 全局常量类应用(枚举、宏) 全大写英文单词组合用下划线分隔 DATA_SIZE 函数命名 第一个单词首字母小写,后面全部首字母大写(或者全部首字母大写,看整体吧) initData()/InitData() 类名 C开头,后面全部首字母大写 CTestObject 接口名 I开头,也是全部首字母大写 ITestObject 类的成员变量 m_开头,首字母大写英文单词组合 m_原创 2021-05-21 12:35:49 · 139 阅读 · 0 评论 -
超详细STL之array容器使用及实现原理解析
说明一下,我用的是gcc7.1.0编译器,标准库源代码也是这个版本的。本篇文章讲述STL中array的使用及原理。导读array其实是一个固定大小的数组,元素类型及大小在声明的时候指定,原型如下:template<typename _Tp, std::size_t _Nm> struct array { ... };有些书上说array也是一个class,但是我这个版本看到的是struct,不过没有关系,除了一些细微的方面,struct和class.原创 2021-05-21 09:25:45 · 1277 阅读 · 0 评论 -
c++中lambda表达式用法
说明一下,我用的是gcc7.1.0编译器,标准库源代码也是这个版本的。本篇文章讲解c++11中lambda表达式用法。初次接触lambda这个关键字,记得还是在python里面,但其实,早在2011年c++11推出来的时候我们c++就有了这个关键字啦。lambda表达式是C++11中引入的一项新技术,利用lambda表达式可以编写内嵌的匿名函数,用以替换独立函数或者函数对象,并且使代码更可读。所谓函数对象,其实就是对operator()进行重载进而产生的一种行为,比如,我们可以在类中,重载函数调用.原创 2021-05-20 10:02:35 · 1793 阅读 · 1 评论 -
最全面的c++中类的构造函数高级使用方法及禁忌
说明一下,我用的是gcc7.1.0编译器,标准库源代码也是这个版本的。本篇文章讲解c++中,构造函数的高级用法以及特殊使用情况。1. 拷贝构造和移动构造区别对于拷贝构造和移动构造,还是看一下这段代码:#include <iostream>#include <string.h>using namespace std;class CPtr{ private: char *m_pData; int m_iSize; public: //without .原创 2021-05-14 09:19:58 · 717 阅读 · 0 评论 -
c++类的构造函数不显式声明会自动生成吗
说明一下,我用的是g++7.1.0编译器,标准库源代码也是这个版本的。本篇文章讲解c++11中,类的构造函数种类,以及不显式声明的情况下是否会自动生成。1. 类的构造函数类别在我刚接触c++的时候,我一直知道类可以有四种形式的构造函数,即无参构造函数、有参构造函数、拷贝构造函数、赋值运算符构造函数,最近看标准IO源代码,发现又多了一种,那就是移动构造函数,这是c++11中补充进来的,所以现在c++可以拥有四种形式的构造函数,即无参构造函数、有参构造函数、拷贝构造函数、赋值构造函数、移动构造函数、移.原创 2021-05-13 09:14:41 · 816 阅读 · 0 评论 -
c语言中strstr函数的一个注意点
今天说一个之前工作上遇到过的一个问题,也是之前没注意过的一个点。先看一段代码:#include <stdio.h>#include <string.h>int main(){ char sz1[16] = {0}; char sz2[10] = {0}; char sz3[3] = {0}; strncpy(sz1, "bbAAcc", sizeof(sz1)-1); strcpy(sz3, "AA"); if ( strstr(sz1, sz2) != NU原创 2021-05-11 09:26:10 · 286 阅读 · 0 评论 -
探究一下c++标准IO的底层实现
说明一下,我用的是g++7.1.0编译器,标准库源代码也是这个版本的。本篇文章讲解c++标准IO的底层实现结构,以及cin和cout的具体实现。在看本文之前,建议先看一下之前的一篇文章,至少要知道标准IO里面各个类之间的关系:c++标准输入输出流关系梳理1. 标准IO的底层结构通过通读c++标准IO的源代码,我总结出了它的底层实现结构,如图:它分为三层结构:外部设备、缓冲区、程序,说明如下:外部设备是指键盘、屏幕、文件等物理或者逻辑设备;缓冲区是指在数据没有同步到外部设备之前,存放数.原创 2021-05-10 09:49:45 · 496 阅读 · 1 评论 -
c++中explicit和mutable关键字探究
今天说一说c++里面的两个关键字explicit和mutable。1. explicit关键字在写c++标准输入输出相关文章,查看iostream实现代码的时候,经常看到构造函数前面带有explicit关键字,那么它到底有什么作用呢。explicit用来防止由构造函数定义的隐式转换,先看这样一段代码:#include <iostream>class Base{private: int a;public: Base(int p_a){ a = p_a;}原创 2021-05-06 09:17:06 · 300 阅读 · 4 评论 -
c++中endl操作符以及它的兄弟们
说明一下,我用的是g++7.1.0编译器,标准库源代码也是这个版本的。一直以来,我们每次使用cout输出数据的时候,如果要换行,都知道使用形如cout << endl;这样的形式,那么endl到底是什么呢,它是怎么样实现输出一个换行符的功能的,以前我没有思考过,但现在我想弄懂它,下面就一起看一下吧。1.endl操作符的实现在标准库头文件<ostream>中,我找到了endl的操作符重载函数,如下:template<typename _CharT, typename .原创 2021-04-30 09:31:11 · 2909 阅读 · 0 评论 -
c++中ifstream及ofstream超详细说明
前文说过,ifstream是继承于istream,ofstream是继承于ostream,fstream是继承于iostream类,而他们使用的缓冲区类是filebuf。关于这些类之间的关系,有兴趣可以去查看我之前的文章:c++标准输入输出流关系梳理1. filebuf类介绍filebuf类又比stringbuf类要复杂一点,毕竟是对文件进行读写,首先在它的成员变量中找到了这样一条声明:__file_type _M_file;_M_file就是它里面的文件操作对象,那么探究一下__file原创 2021-04-28 09:28:34 · 2544 阅读 · 0 评论 -
c++中istringstream及ostringstream超详细说明
文章目录1. stringbuf类介绍1.1 stringbuf类构造函数1.2 str函数2. istringstream类2.1 rdbuf函数2.2 swap函数3.ostringstream类和stringstream类前文说过,istringstream是继承于istream,ostringstream是继承于ostream,而他们使用的缓冲区类是stringbuf。关于这些类之间的关系,有兴趣可以去查看我之前的文章:c++标准输入输出流关系梳理1. stringbuf类介绍string原创 2021-04-26 10:01:17 · 2297 阅读 · 2 评论 -
c++中ostream类的超详细说明
<p>根据前文,ostream类是c++标准输出流的一个基类,本篇详细介绍ostream类的主要成员函数用法。</p><h5 id="1ostream的构造函数">1.ostream的构造函数</h原创 2021-04-19 10:32:04 · 10528 阅读 · 2 评论 -
c++中istream类的超详细说明
根据前文,istream类是c++标准输入流的一个基类,本篇详细介绍istream类的主要成员函数用法。1.istream的构造函数从istream头文件中截取一部分关于构造函数的声明和定义,如下:public:explicit basic_istream(__streambuf_type* __sb) : _M_gcount(streamsize(0)) { this->init(__sb); }protected: basic_istrea原创 2021-04-16 09:33:50 · 14659 阅读 · 2 评论 -
c++标准输入输出流关系梳理
输入输出是每一种编程语言必不可少的部分,c++也不例外,下面我们就来说明c++的标准输入输出的前世今生。1.首先说一下iostream和iostream.h的区别#include<iostream> // 这个就是1998年标准化以后的标准头文件,使用时需要使用声明命名空间std#include<iostream.h> // 这个就是标准化以前的头文件,里面的函数以及类都是全局的iostream是现在C++中规定的标准,目的在于使C++代码用于移植和原创 2021-04-13 09:52:31 · 324 阅读 · 0 评论 -
c++类访问权限及友元
1.类的访问权限class是c++的类声明关键字,它的成员类型有三种,是使用三个关键字来声明的,分别是public、private、protected,public声明的叫做公有成员,private声明的是私有成员,protected声明的则是保护成员。1)public-公有成员首先看一下public声明的公有成员:class A{public: int a; int b;public: int add();private: int sub();protected: int mu原创 2021-04-08 09:47:08 · 890 阅读 · 2 评论 -
memcpy函数的实现
1.按1个字节拷贝(1)不要直接使用形参,要转换成char*(2)目标地址要实现保存(3)要考虑源和目标内存重叠的情况void * mymemcpy(void *dest, const void *src, size_t count){ if (dest == NULL || src == NULL) return NULL; char *pdest ...原创 2019-05-06 16:16:12 · 831 阅读 · 0 评论 -
c++动态分配浅析
1. c语言中动态分配和释放.在c中,申请动态内存是使用malloc和free,这两个函数是c的标准库函数,分配内存使用的是系统调用,使用它们必须包含stdlib.h,才能编译通过。malloc后需要检查内存是否分配成功,free则要在指针不为空的情况下。2. c++动态分配和释放。c++中,申请动态内存是使用new和delete,这两个关键字实际上是运算符,并不是函数。需要注意的是:n...原创 2019-05-06 16:14:10 · 307 阅读 · 0 评论 -
linux c/c++知识点整理(五)
41、linux系统进程间通信方式 管道、有名管道、信号量、消息队列、信号、共享内存、socket、文件 管道及有名管道:管道可用于具有亲缘关系进程间的通信,例如父子进程,但是有名管道允许无关系的进程间通信。管道其实就是建立一个FIFO文件,一个进程往里面写数据,另外的进程读取数据。 信号量:主要作为进程间以及同一进程不同线程之间的同步手段。原创 2017-04-26 10:14:44 · 781 阅读 · 0 评论 -
linux c/c++知识点整理(四)
31、printf输出时在%和字母之间插入数字表示场宽的规则? 当实际长度不够时, 右对齐; 如果字符串或者整数的长度超过说明的场宽, 则按其实际长度输出; 如果是浮点数, 若整数部分超过了说明的整数位场宽, 则按其实际长度输出, 若是小数部分超过了说明的小数位场宽, 则按说明的宽度以四舍五入输出。32、逗号表达式? 例如:printf(“%d原创 2017-04-25 13:43:46 · 469 阅读 · 0 评论 -
linux c/c++知识点整理(三)
21、类成员函数的重载、覆盖和隐藏的区别 重载即为函数重载,重载的特征: (1)相同的范围,也就是在同一个类中 (2)函数名字相同 (3)参数不同 (4)virtual关键字无影响 覆盖是指派生类函数覆盖基类函数,覆盖的特征: (1)不同的范围,即函数分别位于派生类和基类 (2原创 2017-04-24 09:18:40 · 573 阅读 · 0 评论 -
linux c/c++知识点整理(二)
11、关联、聚合、组合的区别 主要是在画uml类图时,有关联、聚合和组合的说法。 关联,是一种很弱的联系,指的是两个类之间有某种联系,比如一个类实例作为另一个类方法的参数; 聚合,指的是整体与部分的关系。通常在定义一个整体类后,再去分析这个整体类的组成结构。从而找出一些组成类,该整体类和组成类之间就形成了聚合关系。例如一个航母编队包括海空母舰、驱护舰艇、舰原创 2017-04-23 17:22:31 · 451 阅读 · 0 评论 -
linux c/c++知识点整理(一)
1、c/c++申请动态内存 在c++中,申请动态内存是使用new和delete,这两个关键字实际上是运算符,并不是函数。 而在c中,申请动态内存则是使用malloc和free,这两个函数是c的标准库函数,使用它们必须包含stdlib.h,才能编译通过。 new/delete和malloc/free的相同之处在于,new和malloc都是手动申请动态内存,释原创 2017-04-23 01:19:05 · 650 阅读 · 0 评论 -
linux c/c++ 面试题目整理(三)
20、用户输入M、N值, 从1到N开始循环数数, 每次数到M就输出当前数据, 直到全部输出,写出C程序。//这是约瑟夫方法,可使用循环链表,用取余操作数,也可用数组,下面是c语言的数组程序:void yuesef(int M,int N){ int* p = new int[N]; int s = 0,r = 0; for(int i=0;i<N;i++) {原创 2017-04-21 15:23:54 · 565 阅读 · 0 评论