win7iis如何做网站,网站推广的基本方法,安庆市网站建设,微网站开发提供的服务基本语法
1、static关键字的作用
1、全局静态变量 加了static关键字的全局变量只能在本文件中使用。 存储在静态存储区#xff0c;整个程序运行期间都存在。 2、局部静态变量 作用域仍为局部作用域。 不过离开作用域之后#xff0c;并没有销毁#xff0c;而是贮存程序中整个程序运行期间都存在。 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_ptrweak_ptr 只提供了对管理对象的一个访问手段。 weak_ptr 的构造和析构不会引起计数的增加或减少。它是用来解决shared_ptr相互引用时的死锁问题如果两个shared_ptr相互引用这两个指针的引用计数永远不可能降为0资源永远不会释放。 举例 在Man类内部会引用一个WomanWoman类内部也引用一个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在遇到重载时可能会出现问题。 智能指针:C11新增了std::shared_ptr、std::weak_ptr等类型的智能指针用于解决内存管理的问题。 初始化列表:使用初始化列表来对类进行初始化。 右值引用:基于右值引用可以实现移动语义和完美转发消除两个对象交互时不必要的对象拷贝节省运算存储资源提高效率。
20、右值
C中左值通常指可以取地址有名字的值就是左值而不能取地址没有名字的就是右值。而在指C11中右值是由两个概念构成将亡值和纯右值。纯右值是用于识别临时变量。 右值引用就是对一个右值进行引用的类型。 更加详细的区别可以看这篇笔记 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向堆区申请空间如果申请失败就看自由链表上有没有可用的块如果没有就调用一级空间配置。