![](https://img-blog.csdnimg.cn/20210108165838551.jpg?x-oss-process=image/resize,m_fixed,h_224,w_224)
C++
文章平均质量分 80
C++从入门到精通
WhiteShirtI
不管你现在是什么状态 你要记住 生活中的目标就是快乐自由 每天开心
展开
-
C++ 一篇文章让你知道智能指针的魅力
前情提要我们知道除了静态内存和栈内存外,每个程序还有一个内存池,这部分内存被称为自由空间或者堆。程序用堆来存储动态分配的对象即那些在程序运行时分配的对象,当动态对象不再使用时,我们的代码必须显式的销毁它们。在C++中,动态内存的管理是用一对运算符完成的:new和delete,ne:在动态内存中为对象分配一块空间并返回一个指向该对象的指针,delete指向一个动态独享的指针,销毁对象,并释放与之关联的内存。动态内存管理经常会出现两种问题:一种是忘记释放内存,会造成内存泄漏;一种是尚有指针引用内存的情况下原创 2021-05-31 21:07:59 · 2354 阅读 · 12 评论 -
C++ lambda表达式
lambda表达式最先出现于python脚本语言,在运行时候才会一行一行的解释指令,速度虽然满,但是对于程序员来说减少了大量的代码工作,语法相对更加简单lambda表达式是一个匿名的函数完整表达式:[capture-list](parameters)mutable->return-type{statement}[]中的变量就是可以将上下文中的变量引入到匿名函数中去使用,默认属性为const()中的变量为函数的参数列表,定义方式和普通函数一样,可省略,但是如果添加mutable属性后即使()为空原创 2021-05-31 10:00:14 · 367 阅读 · 0 评论 -
C++ C++11新特性--右值引用
左值与右值在C语言中,左值和右值一般有两种区分的方法。可以出现在赋值符号“=”的两边的值为左值,只能出现在赋值符号“=”的右边的值为右值;还有一种说法是能取地址的为左值,不能取地址的为右值。但是这两种说法并非完全正确void test(){ int a = 10; int b = a;//ok a为左值 10 = a; //error 10为右值 int* pa = &a;//ok int* pi = &10;//error}而在C++中,右值有3种变量,分别为常量、原创 2021-05-30 21:24:06 · 669 阅读 · 8 评论 -
C++ 布隆过滤器原理及实现
概念布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。例如我们要我找在40亿个数据中查找某字符串是否存在,我们也是第一想到的是通过遍历一个一个去比对,但是数据庞大,遍历消耗很多的时间和空间的资源。但是我们可以通过一位图+哈希来解决这个问题。在常数时间内判断该字符串是否存在。位图+哈希,我们称为布隆过滤器。其原创 2021-05-28 16:17:33 · 826 阅读 · 10 评论 -
C++ 位图及位图的实现
概念位图就是bitmap的缩写,所谓bitmap,就是用每一位来存放某种状态,适用于大规模数据,该数据都是不重复的简单数据。通常是用来判断某个数据存不存在的例如:给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中如果不看数据量,我们第一想到的肯定就是依次从头遍历,但是这个数据量是非常大的,有40亿,遍历40亿次消耗的时间和内存是非常多的。但是引入位图后,就可以专门解决这种大量数据查找是否存在的问题。查找这个数是否存在所消耗的时间复杂度原创 2021-05-28 14:57:51 · 2888 阅读 · 22 评论 -
C++ 简单实现unorderset和unordermap
unorderset和unordermap是C++11中心引入的一种关联式容器。set和map与他们之间的不同之处就是遍历时是否有序,通过名字就可以看出,unorderset和unordermap在遍历时是无序的。之所他们有这样的差异,是因为他们底层的实现的数据结构是不同的,unorderset和unordermap底层是通过哈希表来实现的,而set和map底层是通过红黑树来实现的。unorderset和unordermap的插入和查找的效率非常高,这也会引入他们的原因之一。下面我们一起来看看如何实现的看原创 2021-05-26 16:41:50 · 589 阅读 · 7 评论 -
C++ map的简单实现
map和set的底层都是通过红黑树来实现的,但并不是原生态的红黑树,而是经过改造后的红黑树。且容器都会在各自的类中添加一些独特的函数来解决各自适配的问题map和set底层是改造后的红黑树,我们先来看看改造后的红黑树和普通的红黑树不同的是,在根节点上再加了一个头结点,该结点不是真实的结点,只是一个辅助结点,是为了后面实现红黑树的迭代器而出现的。该header结点的父节点就是真实的根节点,其左孩子是这棵树的最左结点,其右孩子是这棵树的最右节点。我们现在通过STL源码来简单剖析一下map和set中如何利用原创 2021-05-23 13:19:49 · 5552 阅读 · 21 评论 -
C++ 关联容器set | map | multiset | multimap
前情提要根据应用场景的不桶,STL总共实现了两种不同结构的管理式容器:树型结构与哈希结构。树型结构的关联式容器主要有四种:map、set、multimap、multiset。这四种容器的共同点是:使用平衡搜索树(即红黑树) 作为其底层结果,容器中的元素是一个有序的序列。他们都是底层都是通过<key, value>结构的键值对来存储的C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构原创 2021-05-14 13:43:32 · 215 阅读 · 1 评论 -
C++ 面向对象程序三大特性之 多态
多态的概念不同类的对象对同一消息作出不同的响应就叫做多态,通俗来讲,就是去完成某个行为,当不同的对象去完成时会产生出不同的结果例如去网吧上机,如果你是vip,那么你上网的价格就会比普通用户上网的价格低;如果你不是vip,那么你上网的价格就是原价。这就是生活中的一种多态现象多态的定义及使用例如以下程序,就是一种多态的体现class Vip{public: virtual void online() { cout << "7折优惠" << endl; }};原创 2021-05-02 10:45:12 · 1757 阅读 · 7 评论 -
C++ 面向对象程序三大特性之 继承
继承的概念继承:继承是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类的特性的基础上进行扩展,增加功能。产生新的一个类。我们之前复用手段都是通过函数或者模板函数来实现的,而继承上升到类的层次上面。原有的类称为是父类或者基类,而继承了该类的类称为子类或者派生类继承的定义及使用继承格式:class childName : 继承方式 parentName例如下面代码,B类继承了A类//父类 基类class A{public: void printA() { co原创 2021-04-28 11:45:53 · 405 阅读 · 5 评论 -
C++ vector和list的区别及使用场景
区别:1、vector底层是连续结构;list底层是非连续结构2、vector支持随机访问;list不支持随机访问3、vector迭代器是原生指针;list迭代器是封装结点的一个类4、vector在插入和删除时可能会导致迭代器失效;list在删除的时候会导致当前迭代器指向的结点失效5、vector不容易造成内存碎片,空间利用率高;list容易造成内存碎片,空间利用率低6、vector在非尾插,删除的时间复杂度为O(n),list在任何地方插入和删除的时间复杂度都为O(1)使用场景:vecot原创 2021-04-22 20:54:35 · 2631 阅读 · 0 评论 -
C++ 容器适配器(stack、queue、priority_queue)
容器适配器首先,我们要明白适配器是干什么的?其实就是一个接口转换装置,是得我们能用特定的方法去操作一些我们本来无法操作的东西。举一个例子,比如你的一个设备支持串口线,而你的电脑支持的是usb口,这时候,我们没有必要重新买一个支持usb的设备,只需要一根串口转usb口的小玩意,让你的设备能够连接到usb插口上,而它就是适配器。不同场景下,由于不同的序列式容器其底层采用的数据结构不同,因此容器适配器的执行效率也不尽相同。但通常情况下,使用默认的基础容器即可。当然,我们也可以手动修改,如果有了解双端队列原创 2021-04-19 16:44:12 · 161 阅读 · 0 评论 -
C++ 容器适配器priority_queue的使用及实现
优先级队列(Priority Queue)队列是一种特征为FIFO的数据结构,每次从队列中取出的是最早加入队列中的元素。但是,许多应用需要另一种队列,每次从队列中取出的应是具有最高优先权的元素,这种队列就是优先级队列(Priority Queue),也称为优先权队列。1. 优先级队列的概念优先级队列的定义优先级队列是不同于先进先出队列的另一种队列。每次从队列中取出的是具有最高优先权的元素。优先级队列的特点优先级队列是0个或多个元素的集合,每个元素都有一个优先权或值。当给每个元素分配一个数原创 2021-04-19 16:41:33 · 1108 阅读 · 4 评论 -
C++ 什么是伪函数,以及伪函数的使用
函数指针有缺点,最重要的是它无法持有自己的状态(局部状态),也无法达到组件技术中的可适配性(也就是无法再将来某些修饰徐条件加上,以达到改变其状态)。因此,STL算法的特殊版本所接受的所谓的”条件“或”策略“或”一整组操作“都是以仿函数呈现的。所谓仿函数(functor)就是使用起来像函数一样的东西。如果对某个class进行operator()重载,它就是一个仿函数类,该函数就是一个仿函数//仿函数类template<class T>struct Greater{ //仿函数 b原创 2021-04-19 16:25:23 · 2778 阅读 · 0 评论 -
C++ 双端队列deque
双端队列的简单认识双端队列是动态大小的序列式容器,其可以像两端进行伸缩。特定的库可以以不同的方式实现deque,但通常都是一种动态数组。不论在何种情况下,它都允许通过随机访问迭代器直接访问单个元素,可以根据需要动态的伸缩。因此,deque提供了一些与vector相似的功能,但deque在头部和尾部进行数据插入和删除操作更加高效。与vector不同的是,deque不能保证所有的元素存储在连续的空间中,在deque中通过指针加偏移量方式访问元素可能会导致非法的操作。vector与list提供了相似的接口原创 2021-04-19 14:54:51 · 481 阅读 · 0 评论 -
C++ 整形转换为字符串的方式总结
整形转换为字符串itoachar* itoa (int value, char * str, int base)value :要转换的值str:转换后的数据首地址base:以几进制的方式转换注:新版vs中需要加入类型安全检查#define _CRT_SECURE_NO_WARNINGS#define _CRT_NONSTDC_NO_DEPRECATE示例代码:int main(){ int a = 10; char arr[100]; //将a的内容以10进制的方式写到arr中原创 2021-04-18 19:39:12 · 3183 阅读 · 0 评论 -
C++ IO常用读写操作
输出文件流 ofstream头文件: 打开一个文件的方式:1、通过构造函数来打开文件;2、创建一个ofstream对象,调用open方法打开文件 //文件不存在则创建 //1、 ofstream fout("test.txt"); //2、 fout.open("test.txt"); //二进制打开文件 ofstream fout2("testBinary.txt", ifstream::binary); ifstream fin("testBinary.txt", ifstre原创 2021-04-18 19:10:50 · 270 阅读 · 0 评论 -
C++ 泛型模板进阶
非类型模板参数我们平时使用的模板都是和类型有关的,但是也有不是类型也能当做模板来使用,而是在tmplate<>中定义一个变量并给定初始值,这种模板的参数称为非类型模板参数例如在我们array静态数组中,底层的实现就使用到了非类型模板参数使用示例:void test(){ //定义10个int类型的静态数组 //这是在栈上申请的,第二个值不宜太大 //array<class T, size_t N> array<int, 10> arr;}使用注意原创 2021-04-18 18:10:01 · 214 阅读 · 0 评论 -
C++ list类的模拟实现
list类和string与vector不一样,list类的底层是通过双向带头循环链表属性定义由于是带头的链表,为了方便使用我们定义两个类,一个是单独结点的类,一个是属性只有头结点,用于存放结点的List类。//单独结点类template <class T>struct ListNode{ T _data; //结点数据 ListNode<T>* _next; //该结点的下一个结点 ListNode<T>* _prev; //该结点的上一个结点 //原创 2021-04-10 16:57:48 · 1220 阅读 · 5 评论 -
C++ vector类的模拟实现
vector和string虽然底层都是通过顺序表来实现的,但是他们利用顺序表的方式不同,string是指定好了类型,通过使用顺序表来存储并对数据进行操作,而vector是利用了C++中的泛型模板,可以存储任何类型的数据,并且在vector中,并没有什么有效字符和容量大小的说法,底层都是通过迭代器进行操作的,迭代器底层实现也就是指针,所以说,vector是利用指针对任何顺序表进行操作的。vector属性_start用于指向第一个有效元素_finish用于指向最后一个有效元素的下一个位置_endOf原创 2021-04-04 16:33:29 · 4833 阅读 · 14 评论 -
C++ 迭代器失效问题
迭代器的底层是通过指针来实现的,例如string类的迭代器是由char* 类型的指针实现的,vector类是由原生态指针T* 实现的。我们都知道,如果对指针使用不当,会造成程序的崩溃,所以对迭代器的操作,其实就是对指针的操作。所以我们使用时就要确保迭代器的安全性问题迭代器失效我们就拿vector类来详细说明1、操作已释放的空间造成迭代器失效我们来看看以下代码#include <iostream>#include <vector>using namespace std;.原创 2021-03-26 21:12:43 · 2241 阅读 · 6 评论 -
C++ string类的模拟实现
在学习和使用string时,我们用起来都很方便,那是因为底层已经有人帮我们实现了,现在我们来自己实现string类的常用接口,加深对我们string类的认识默认成员函数的实现默认构造函数由于string类是字符串,是需要各种增删查改等操作,所以是一个需要开空间,占用资源的一个类,所以我们在实现默认构造函数时必须要申请空间。错误示范一 :没有申请空间string(const char* str){ strcpy(_str, str);}错误示范二:缺省值错误string(const ch原创 2021-03-21 20:48:20 · 480 阅读 · 10 评论 -
C++ STL容器之string--常用接口
目录学前必须掌握知识string类对象的常见构造常见的访问字符串操作string中迭代器的使用string有关容量的常见接口常见修改string字符串的接口学前必须掌握知识string字符串是表示字符序列的类,标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作 单字节字符字符串的设计特性。string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator>原创 2021-03-15 16:42:17 · 576 阅读 · 0 评论 -
C++ 泛型编程的基础--模板初识及应用
了解模板之前我们要先知道什么是泛型编程:型编程的代表作品STL是一种高效、泛型、可交互操作的软件组件。STL以迭代器 (Iterators)和容器(Containers)为基础,是一种泛型算法(Generic Algorithms)库。泛型编程让你编写完全一般化并可重复使用的算法,其效率与针对某特定数据类型而设计的算法相同。泛型即是指具有在多种数据类型上皆可操作的含义,而模板也是泛型编程中的一种典型例子。函数模板模板我们生活中也听得不少了,建房时都会有图纸,然后人们可以通过图纸来建房的基本框架。有了基本原创 2021-03-15 12:52:01 · 336 阅读 · 0 评论 -
C++ 涨知识!new和delete知识总结(全面详细)
回顾C学C++的小伙伴之前一定有学过C吧,C语言申请空间都是在堆区上开辟的,而申请的方式有3种;malloc、calloc和realloc。malloc:函数原型void* malloc(size_t size) 参数size为要分配的字节数,返回值是void*,通常要强转为我们需要申请空间的类型,开辟成功回返回空间首地址,失败会返回NULL,但是申请成功后并不进行初始化,每个数据都是随机值。calloc:函数原型void* calloc(size_t number, size_t size); 参数原创 2021-03-14 22:19:41 · 33598 阅读 · 18 评论 -
C++ static静态成员 和 友元函数与友元类、内部类
static静态成员变量在成员变量前加static,该成员称为静态成员变量static int _count;在成员函数前加static,该函数称为静态成员函数 static int getCount() { return _count; }代码示例class A{public: static int getCount() { return _count; }private: static int _count;};//类外定义int A::_count原创 2021-03-04 18:31:35 · 1240 阅读 · 2 评论 -
C++ explicit关键字
我们先看下面的代码class A{public: //构造函数 A(int a = 0) :_a(a) {} //拷贝构造 A(const A& a) { _a = a._a; }private: int _a;};int main(){ A b(10); //构造 A c = b; //拷贝构造 A d = 20; //单参构造隐式类型转换}在main函数中d对象居然可以用一个int类型的常量来实例化,其实这是编译器对这样子的实例化进行了优化。原创 2021-03-04 17:31:36 · 128 阅读 · 1 评论 -
C++ 初始化列表
我们都知道,成员变量的初始化是在构造函数中完成的,而我们之前在构造函数的函数体内写的赋值操作,其实并不是初始化,因为,而是普通的赋值操作。初始化只能被初始化一次,而赋值操作可以被赋值多次。那我们怎样才能完成成员变量的初始化呢,这时候就引进了–初始化列表格式: 以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式class Date {public: Date(int year, int month, int day) //初始化列表原创 2021-03-04 17:11:55 · 1832 阅读 · 4 评论 -
C++ const对成员函数的修饰 及 取地址及const取地址操作符重载
将const修饰的类成员函数称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this 指针,表明在该成员函数中不能对类的任何成员进行修改。格式为 void menberFun() const因为this指针是隐含的,我们无法在this指针前添加const,所以我们只能在函数后面加const...原创 2021-02-06 11:41:44 · 775 阅读 · 0 评论 -
C++ 拷贝构造 与 赋值运算符重载
拷贝构造当我们创建了一个对象时,想让它的内容和一个已经创建好的对象的内容相同,那么就必须用到拷贝构造。拷贝构造编译器也会自动生成,也是C++类中的6个默认函数之一。拷贝构造函数格式类名(const 类名& 变量名)class Date{public: Date(int year = 1, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } //拷贝构造函数 Date(原创 2021-02-03 18:05:18 · 697 阅读 · 0 评论 -
C++ 构造函数 与 析构函数
在我们C++类中,默认会有6个默认的成员函数,即使我们不写,也至少会有6个成员函数,分别是:构造函数、析构函数、拷贝构造、赋值操作符重载、取地址操作符重载、const修饰的取地址操作符重载。构造函数构造函数的功能就是给实例化出来的对象初始化。相当于在对象在被实例化的同时赋予初始值。类也是一种类型,是我们自定义的类型,那我们想要让我们自定义的类型像内置类型一样使用,就肯定离不来我们的默认的成员函数。对于内置类型,可以在定义时初始化int num = 5,定义变量num并初始化num为5。那我们的自定义类原创 2021-02-03 17:18:56 · 769 阅读 · 0 评论 -
C++ 初识类与对象
C++是一门面向对象的编程语言,那类与对象也就是C++的核心部分,现在让我们一起来学习类与对象吧。初识类与对象类的定义类的限定符封装类的实例化类对象模型类的大小类的定义定义一个类我们可以用到关键字struct和class,在C语言中我们都学过结构体,对struct并不陌生。但是在C++中的struct与C中的结构体又有一些差距,可以这么说,就是因为C++兼容了C,才将struct保留下来。在C语言中的结构体,只能定义变量,使用变量,而在C++中的结构体,既可以定义变量,也可以定义函数。这就是C++.原创 2021-01-31 16:01:48 · 490 阅读 · 0 评论 -
C++ 面向对象与面向过程的区别与联系
转自:https://blog.csdn.net/jerry11112/article/details/79027834 前言: 如果你很想搞明白面向对象是什么,面向过程是什么,或者说二者之间的区别是什么,那么就花费一点时间来研读一下这篇博客,你一定会有很大的收获的! 一、面向对转载 2021-01-31 14:48:48 · 1725 阅读 · 0 评论 -
C++ C++基础语法入门总结(二)引用-内联函数-C++11新特性
C++基础语法入门总结引用引用引用:就是某一变量(目标)的一个别名,共用一块内存空间,对引用的操作就是对变量(目标)的操作。格式:类型& 引用变量名(对象)= 引用实体引用大家可以理解为给别人取外号。你喊他的外号或者喊他大名,他都会理你。相信大家都看过西游记吧,在西游记中的孙悟空也有很多外号,例如,美猴王、孙行者、齐天大圣、斗战圣佛等。一提到其中的一个外号,都会知道是猴子孙悟空。下面给我们来深入了解引用和使用方法 int a = 10; //ra是a的一个别名 int& r原创 2021-01-29 19:24:23 · 356 阅读 · 0 评论 -
C++ C++基础语法入门总结(一)命名空间-输入输出-缺省参数-函数重载
C++ 命名空间其实在C语言中也有命名空间这一说法,只是在C语言中只有全局和函数的命名空间,就是在各自的作用域中使用同名变量、函数等等都不会受到影响。而在C++中,为了避免同名变量、函数、类等的冲突,引入了命名空间,目的是对标识符的名称进行本地化。如何定义和使用命名空间命名格式:namespace 命名空间名称 {变量 + 函数}定义命名空间的三种方式1、普通的命名空间namespace N1{ int a = 1; void fun1() { printf("N1: fun1原创 2021-01-28 18:40:27 · 428 阅读 · 0 评论 -
C++ C++的发展史
C++的发展史前言记住 Vasa实践中的 C++C++ 的未来C++历史版本强大、灵活、复杂:C++ 的起源可以追溯到 40 年前,但它仍然是当今使用最广泛的编程语言之一。前言C++ 的起源可以追溯到 1979 年,那时编程语言的创造者 Bjarne Stroustrup 第一次开始研究 C++ 这门语言,当时被称为“带类的 C”(C with Classes)。该语言的设计初衷是作为对 C 编程语言的改进,添加了一些基于面向对象编程的功能。Stroustrup 告诉 TechRepublic原创 2021-01-28 15:29:44 · 1335 阅读 · 0 评论