C++基础知识点整理

在这里插入图片描述

基本语法

1、static关键字的作用

1、全局静态变量
加了static关键字的全局变量只能在本文件中使用。
存储在静态存储区,整个程序运行期间都存在。
2、局部静态变量
作用域仍为局部作用域。
不过离开作用域之后,并没有销毁,而是贮存程序中,不能进行访问,除非函数再次被调用。
3、静态函数
只能在声明它的文件中使用,不能被其他文件使用,也不会和其他cpp中的同名函数起冲突。
4、类的静态成员
使用静态成员可以实现多个对象之间的数据共享,也不会破坏隐藏原则。静态数据成员只存储于一处,供所有对象共用。
5、类的静态函数
属于类的静态成员,对静态成员引用不需要对象名。注意,静态成员函数的实现中不能直接引用类中非静态成员,可以直接引用类中的静态成员。

2、C++四种cast转换

const_cast : 用于将const变量转为非const.
static_cast : 用于各种隐式转换,用于多态向上转换,向下转换不安全
dynamic_cast : 用于动态类型转换,用于类层次间的向上向下转化。只能转指针或者引用。
对于指针,转换失败返回nullptr,对于引用,转换失败会抛出异常。
向上:子类向基类转化
向下:基类向子类转化
reinterpret_cast:几乎都可以转化,可能会出问题
C语言的强制转换不能进行错误检查。

3、指针与引用区别

1、指针有自己空间,引用是一个别名
2、sizeof指针为4,引用是被引用对象的大小
3、指针可以初始化为NULL,引用被初始化必须是一个已有对象的引用
4、指针可以指向其他对象,引用只能是一个对象的引用,不能被改变
5、指针可以多级,引用只有1级
6、返回动态内存分配的对象,使用指针。

4、智能指针

作用:
申请的空间在函数结束时忘记释放,造成内存泄漏。
智能指针是一个类,当超出了类的作用域,类会自动调用析构函数,析构函数自动释放资源,这样就不需要手动释放内存了。
auto_ptr : 存在隐患
unique_ptr : 保证了同时只有一个智能指针指向该对象。
shared_ptr : 多个智能指针可以指向相同对象,该对象和相关的资源会在最后一个引用被销毁的时候释放。
其成员函数use_count() 用来查看资源所有者个数。
调用release,当前指针会释放资源所有权,计数减一。
weak_ptr : 不控制对象生命周期,它指向一个shared_ptr管理的对象。
进行该对象的内存管理的是shared_ptr,weak_ptr 只提供了对管理对象的一个访问手段。
weak_ptr 的构造和析构不会引起计数的增加或减少。它是用来解决shared_ptr相互引用时的死锁问题:如果两个shared_ptr相互引用,这两个指针的引用计数永远不可能降为0,资源永远不会释放。
举例:
在Man类内部会引用一个Woman,Woman类内部也引用一个Man。当一个man和一个woman是夫妻的时候,他们直接就存在了相互引用问题。man内部有个用于管理wife生命期的shared_ptr变量,也就是说wife必定是在husband去世之后才能去世。同样的,woman内部也有一个管理husband生命期的shared_ptr变量,也就是说husband必须在wife去世之后才能去世。这就是循环引用存在的问题:husband的生命期由wife的生命期决定,wife的生命期由husband的生命期决定,最后两人都死不掉,违反了自然规律,导致了内存泄漏。
https://blog.csdn.net/shanno/article/details/7363480

5、数组与指针

在这里插入图片描述

6、野指针

野指针就是指向一个已删除的对象或者未申请访问受限内存区域的指针

7、智能指针内存泄漏如何解决

智能指针的内存泄漏主要是由于循环引用造成的。可以引入weak_ptr指针。weak_ptr的构造函数不会修改引用计数的值,从而不会对对象的内存进行管理,类似一个普通指针,但不指向引用计数的共享内存。weak_ptr可以检测到所管理的对象是否被释放,从而避免非法访问。

8、析构函数必须是虚函数

如果父类的析构函数不是虚函数,那么当我们new一个子类对象,然后使用基类指针指向该子类对象,释放基类指针时就只会释放基类对象,子类对象的空间不会被释放,从而造成内存泄漏。

C++默认的析构函数不是虚函数,是因为虚函数需要额外的虚函数表和虚表指针,占用额外内存。如果这个类不会被继承,析构函数设为虚函数反而会造成内存浪费。

9、函数指针

函数指针是指向函数的指针变量。
C在编译的时候,每个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可以用该指针调用函数。
用途:
调用函数和做函数的参数,如回调函数

10、析构函数作用

在这里插入图片描述

11、静态函数与虚函数的区别

静态函数在编译的时候就已经确定了运行机制,虚函数在运行的时候动态绑定。虚函数因为有虚函数表机制,调用的时候会增加一次内存开销。

12、重载与覆写

重载:两个函数名字相同,但是参数列不同
覆写:子类继承父类,父类中的函数是虚函数,在子类中重新定义这个虚函数。

13、虚函数与多态理解

多态分为静态与动态。静态多态通过重载,在编译时就确定了。
动态多态是用虚函数机制实现的,在运行期间动态绑定。
举例:一个父类类型的指针指向一个子类对象的时候,使用父类指针调用子类中的虚函数时,调用的就是子类覆写后的函数。

14、const修饰成员函数

表明函数调用不会对对象做出任何更改。
如果确认不会对对象做更改,更应该为函数加上const限定。

15、隐式类型转换

对于内置类型,低精度的变量给高精度的变量赋值会发生隐式类型转换。

16、虚函数的实现

在有虚函数的类中,类的最开始部分时一个虚函数表的指针,这个指针指向一个虚函数表,表中放了虚函数的地址,实际的虚函数在代码段(.text)中。当子类继承了父类的时候也会继承其虚函数表,当子类重写父类中虚函数时候,会将其继承到的虚函数表地址替换为重新写的函数地址。使用了虚函数,回增加访问内存开销,降低效率。

17、C++中怎么定义常量?常量存放在内存的哪个位置

常量定义必须初始化。对于局部对象,常量存放在栈区,对于全局对象,常量存放在全局/静态存储区。杜宇字面值常量,常量存放在常量存储区。

18、auto、nullptr关键字

auto关键字:编译器可以根据初始值自动推导出类型。但是不能用于函数传参以及数组类型的推导。
nullptr关键字: nullptr是一种特殊类型的字面值,它可以被转换成任意其它的指针类型;而NULL一般被宏定义为0,在遇到重载时可能会出现问题。
智能指针:C++11新增了std::shared_ptr、std::weak_ptr等类型的智能指针,用于解决内存管理的问题。
初始化列表:使用初始化列表来对类进行初始化。
右值引用:基于右值引用可以实现移动语义和完美转发,消除两个对象交互时不必要的对象拷贝,节省运算存储资源,提高效率。

20、右值

C++中,左值通常指可以取地址,有名字的值就是左值,而不能取地址,没有名字的就是右值。而在指C++11中,右值是由两个概念构成,将亡值和纯右值。纯右值是用于识别临时变量。
右值引用就是对一个右值进行引用的类型。
更加详细的区别可以看这篇笔记:
https://blog.csdn.net/qq_42604176/article/details/110941759

21、lambda表达式

Lambda 是一个匿名函数,可以把 Lambda表达式 理解为是一段可以传递的代码 (将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。
比如你代码里有一些小函数,而这些函数一般只被调用一次(比如函数指针),这时你就可以用lambda表达式替代他们,这样代码看起来更简洁些,用起来也方便。
具体用途和理解看这儿:
Lambda 表达式有何用处

容器

1、STL迭代器删除元素迭代器失效

1、对于序列容器来说,使用erase后,后面的每个元素的迭代器都会失效,但是后面每个元素都会向前移动一个位置,然后返回下一个有效的迭代器。

2、对于关联容器来说,使用erase后,当前元素迭代器失效,但由于其内部结构,删除当前元素不会影响到下一个元素的迭代器。只需要在调用erase之前,记录下一个元素的迭代器即可。

3、对于list来说,它使用了不连续分配的内存,而且erase方法也会返回下一个有效的iterator,所以两个方法都可以使用

2、STL由什么组成

容器、迭代器、仿函数、算法、分配器、容器适配器

分配器给容器分配存储空间,算法通过迭代器获取容器中的内容,仿函数协助算法完成操作,适配器用来适配仿函数。

3、vector 与 list区别

vector
连续存储的容器,动态数组,在对上分配空间。

底层实现:数组

两倍容量增长:

vector增加插入元素的时候,如果未超过当时的容量,则还有剩余空间,那么直接添加到最后位置,然后调整迭代器。

如果没有剩余空间了,则会重新配置原有元素个数的两倍空间,然后将原空间元素通过复制的方式初始化新空间,再向新空间增加元素,最后析构释放掉原来空间,之前的迭代器会失效。
list
list
底层:双向链表

4、STL中迭代器的作用,有指针为何还要迭代器

底层

1、C/C++内存分布

虚拟内存被分为代码段、数据段、bss段、堆区、文件映射区、栈区。
代码段:只读存储区、文本区。只读存储区存储字符串常量、文本区存储程序的代码
数据段:存储程序中已经初始化的全局变量和静态变量
bss段:存储未初始化的全局变量和静态变量
堆区:程序员动态分配内存,并由程序员手动释放
映射区:存储动态链接库以及调用mmap函数进行文件映射
栈:存储函数的返回地址、参数、局部变量、返回值

2、malloc底层原理

malloc采用内存池的方式,先申请大块内存作为堆区,然后将堆区分割为很多个内存块,以块作为内存管理的基本单元。当用户申请内存时,直接从堆区分配一块合适的空闲块。malloc使用隐式链表来将堆区分成连续的、大小不一的内存块。同时使用显示链表管理所有内存块,即使用一个双向链表将空闲链表连接起来。
当分配内存时,malloc会通过隐式链表遍历所有空闲块,选择满足要求的块进行分配;
当内存合并时,malloc采用边界标记法,根据每个块的前后块是否已经分配来决定是否将块合并。

当申请内存小于128k,会使用brk在堆区分配。当申请内存大于128k时,使用mmap在映射区分配。

3、内存泄漏分类

1、堆内存泄漏:new和delete没有对应上
2、系统资源泄漏:程序使用系统分配的资源,然后没有相应的函数释放,导致系统资源浪费。
3、没有将基类的析构函数定义为虚函数。当基类指针指向子类对象,如果基类析构函数不是虚函数,那么子类的析构函数就不会被调用,子类的资源就没有被释放。

4、STL内存优化

使用二级配置器结构。
1、第一级配置器
如果申请内存大于128字节的空间,如果分配不成功,就调用句柄释放内存,如果还不能分配成功就会抛异常
2、第二级配置器,每次配置一大块内存,并维护16个自由链表。
处理小于128字节的申请。
首先将申请空间扩展到8倍数,然后从freelist查找对应大小的子链表。
如果该自由链表下没有挂内存,或者挂的内存块太少了,就向内存池申请,一般来说申请20块内存。
如果内存池空间足够,取出内存。如果不够,就分配出最多的块数给自由链表。如果一块都无法提供,则把剩余的内存挂到最符合的自由链表上。然后调用malloc向堆区申请空间,如果申请失败就看自由链表上有没有可用的块,如果没有,就调用一级空间配置。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/377285.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

组合问题 已知组合数_组合和问题

组合问题 已知组合数Description: 描述: This is a standard interview problem to make some combination of the numbers whose sum equals to a given number using backtracking. 这是一个标准的面试问题,它使用回溯功能将总和等于给定数字的数字进…

可变参数模板、右值引用带来的移动语义完美转发、lambda表达式的理解

可变参数模板 可变参数模板对参数进行了高度泛化&#xff0c;可以表示任意数目、任意类型的参数&#xff1a; 语法为&#xff1a;在class或者typename后面带上省略号。 Template<class ... T> void func(T ... args) {// }T:模板参数包&#xff0c;args叫做函数参数包 …

python 子图大小_Python | 图的大小

python 子图大小In some cases, the automatic figure size generated by the matplotlib.pyplot is not visually good or there could be some non-acceptable ratio in the figure. So, rather than allowing a pyplot to decide the figure size, we can manually define t…

《设计模式整理》

目录常见设计模式如何保证单例模式只有一个实例单例模式中的懒汉与饿汉模式OOP设计模式的五项原则单例模式中的懒汉加载&#xff0c;如果并发访问该怎么做常见设计模式 单例模式&#xff1a; 单例模式主要解决了一个全局使用的类频繁的创建和销毁的问题。 单例模式下确保某一个…

JSON学习资料整理

1.什么是JSON JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于JavaScript的一个子集。 JSON采用完全独立于语言的文本格式&#xff0c;但是也使用了类似于C语言家族的习惯&#xff08;包括C, C, C#, Java, JavaScript, Perl, Python等&#xff09;。这些…

OSI七层模型及其数据的封装和解封过程

OSI(Open System Interconnection)参考模型把网络分为七层: 1.物理层(Physical Layer) 物理层主要传输原始的比特流,集线器(Hub)是本层的典型设备; 2.数据链路层(Data Link Layer) 数据链路层负责在两个相邻节点间无差错的传送以帧为单位的数据,本层的典型设备是交换机(Switch)…

rss聚合模式案例_RSS的完整形式是什么?

rss聚合模式案例RSS&#xff1a;真正简单的联合 (RSS: Really Simple Syndication) RSS is an abbreviation of Really Simple Syndication. It is also called Rich Site Summary. It is quality attainment for the syndication of collection of web content and used to di…

《MySQL——38道查询练习(无连接查询)》

目录一、准备数据1、创建数据库2、创建学生表3、创建教师表4、创建课程表5、创建成绩表6、添加数据二、查询练习1、查询 student 表的所有行2、查询 student 表中的 name、sex 和 class 字段的所有行3、查询 teacher 表中不重复的 department 列4、查询 score 表中成绩在60-80之…

XPth和XSLT的一些简单用法

&#xff08;目的在于让大家知道有这个东西的存在&#xff09; XPath:即XML Path语言(Xpath)表达式使用路径表示法(像在URL中使用一样)来为XML文档的各部分寻址&#xff01; 关于XPath如何使用了&#xff0c;我们来看看&#xff01;当然这里面的代码只是入门&#xff0c;更深层…

isc dhcp_ISC的完整形式是什么?

isc dhcpISC&#xff1a;印度学校证书 (ISC: Indian School Certificate) ISC is an abbreviation of the Indian School Certificate. It alludes to the 12th class examination or higher secondary examination conducted by the Council for the Indian School Certificat…

《MySQL——连接查询》

内连接&#xff1a; inner join 或者 join 外连接 1、左连接 left join 或 left outer join 2、右连接 right join 或 right outer join 3、完全外连接 full join 或 full outer join 图示理解 全连接 创建person表和card表 CREATE DATABASE testJoin;CREATE TABLE person (…

win7下 apache2.2 +php5.4 环境搭建

这篇文章很好 没法复制 把链接粘贴来http://www.360doc.com/content/13/0506/13/11495619_283349585.shtml# 现在能复制了&#xff1a; 把任何一篇你要复制、却不让复制的文章收藏入收藏夹(直接CtrlD,确定) 2在收藏夹中&#xff0c;右击刚才收藏的那个网址&#xff0c;点属性 3…

运行在TQ2440开发板上以及X86平台上的linux内核编译

一、运行在TQ2440开发板上的linux内核编译 1、获取源码并解压 直接使用天嵌移植好的“linux-2.6.30.4_20100531.tar.bz2”源码包。 解压&#xff08;天嵌默认解压到/opt/EmbedSky/linux-2.6.30.4/中&#xff09; tar xvjf linux-2.6.30.4_20100531.tar.bz2 -C / 2、获取默认配置…

Python熊猫– GroupBy

Python熊猫– GroupBy (Python Pandas – GroupBy) GroupBy method can be used to work on group rows of data together and call aggregate functions. It allows to group together rows based off of a column and perform an aggregate function on them. GroupBy方法可用…

MySQL索引底层原理理解以及常见问题总结

目录二叉查找树为索引红黑树为索引B树作为索引B树作为索引MyISAM存储引擎索引实现InnoDB存储引擎索引实现常见问题聚集索引与非聚集索引InnoDB基于主键索引和普通索引的查询有什么区别&#xff1f;InnoDB主键索引为何是整型的自增主键何时使用业务字段作为主键呢&#xff1f;哈…

des算法密码多长_密码学中的多个DES

des算法密码多长This is a DES that was susceptible to attacks due to tremendous advances in computer hardware in cryptography. Hence, it was a very complex or competent algorithm it would be feasible to reuse DES rather than writing an of cryptography. 由于…

《MySQL——索引笔记》

目录回表覆盖索引最左前缀原则联合索引的时候&#xff0c;如何安排索引内的字段顺序&#xff1f;索引下推重建索引问题联合主键索引和 InnoDB 索引组织表问题in与between的区别回表 回到主键索引树搜索的过程&#xff0c;我们称为回表。 覆盖索引 覆盖索引就是在这次的查询中…

《操作系统知识点整理》

目录进程与线程比较多线程同步与互斥生产者与消费者哲学家就餐问题读者写者问题进程间通信管道消息队列共享内存信号量信号Socket锁互斥锁与自旋锁读写锁乐观锁与悲观锁死锁进程与线程比较 进程是资源&#xff08;包括内存、打开的文件等&#xff09;分配的单位&#xff0c;线…

操作系统大内核和微内核_操作系统中的内核

操作系统大内核和微内核A Kernel is the central component of an Operating System. The Kernel is also said to be the heart of the Operating System. It is responsible for managing all the processes, memory, files, etc. The Kernel functions at the lowest level …

《MySQL——锁》

全局锁是什么&#xff1f;全局锁有什么用&#xff1f;全局锁怎么用&#xff1f; 全局锁主要用在逻辑备份过程中&#xff0c;对于InnoDB 引擎的库&#xff0c;使用–single-transaction; MySQL 提供了一个加全局读锁的方法&#xff0c;命令是 Flush tables with read lock (FTW…