C++
瞎子my
这个作者很懒,什么都没留下…
展开
-
智能指针
C++程序设计中,使用堆内存是很繁琐的操作——堆内存的申请和释放都需要程序员自己去管理。虽然说程序员自己管理内存可以提高程序的效率,但是整体来说程序员手动管理内存是比较麻烦的,而且容易出现内存泄漏,异常安全(如果在malloc和free之间如果存在抛异常,那么还是有内存泄漏)等问题。而在C++11中引入了智能指针的概念来管理堆内存。智能指针的实现采用了一种RAII(利用对象生命周期来控制程序资源...原创 2019-04-11 23:50:06 · 213 阅读 · 0 评论 -
模板
如何实现一个通用的函数呢?(如针对不同的参数类型均可)在平时的编程中,如何实现一个通用的函数呢?首先想到的就是使用函数重载,但是这样一来会有几个不好的地方:重载的函数仅仅只是类型不同,代码的复用率比较低,只要有新类型出现时就需要增加对应的函数代码可维护率比较低,一个函数出错就有可能所有的重载都出错那么有没有一种方式,使得编译器可以根据不同的类型来利用该模子来生成代码呢?答案是有的—...原创 2019-05-18 21:42:22 · 198 阅读 · 0 评论 -
C-11新特性
可变参数模板:C++11的可变参数模板,对参数进行了高度泛化,可以表示任意数目、任意类型的参数,其语法为:在class或typename后面带上省略号”。例如:Template<class … T>void func(T … args){cout<<”num is”<<sizeof …(args)<<endl;}func();//ar...原创 2019-05-30 22:35:41 · 2894 阅读 · 0 评论 -
程序内存管理
程序内存管理:一个程序本质上都是由BSS段、data段、text段三个组成的。可以看到一个可执行程序在存储**(没有调入内存)时分为代码段、数据区和未初始化数据区三部分。**BSS段(未初始化数据区):通常用来存放程序中未初始化的全局变量和静态变量的一块内存区域。BSS段属于静态分配,程序结束后静态变量资源由系统自动释放。数据段:存放程序中已初始化的全局变量的一块内存区域。数据段也属于静态...原创 2019-06-05 22:39:32 · 607 阅读 · 0 评论 -
Top-K问题
1、直接全部排序(只适用于内存够的情况)当数据量较小的情况下,内存中可以容纳所有数据。则最简单也是最容易想到的方法是将数据全部排序,然后取排序后的数据中的前K个。这种方法对数据量比较敏感,当数据量较大的情况下,内存不能完全容纳全部数据,这种方法便不适应了。即使内存能够满足要求,该方法将全部数据都排序了,而题目只要求找出top K个数据,所以该方法并不十分高效,不建议使用。2、快速排序的变形 ...原创 2019-06-12 22:20:19 · 3456 阅读 · 0 评论 -
类中成员内存分布
static修饰符static修饰成员变量对于非静态数据成员,每个类对象都有自己的拷贝。而静态数据成员被当做是类的成员,无论这个类被定义了多少个,静态数据成员都只有一份拷贝,为该类型的所有对象所共享(包括其派生类)。所以,静态数据成员的值对每个对象都是一样的,它的值可以更新。因为静态数据成员在全局数据区分配内存,属于本类的所有对象共享,所以它不属于特定的类对象,在没有产生类对象前就可以使用。...原创 2019-06-06 22:07:59 · 605 阅读 · 0 评论 -
覆盖与隐藏
题目链接:https://www.nowcoder.com/questionTerminal/f29ec891b0284259a922d0dae964ef3a来源:牛客网下面程序的输出是()class A{ public: void foo() { printf("1"); } virtual void...原创 2019-06-01 22:44:37 · 613 阅读 · 0 评论 -
排序算法
插入排序对于一个带排序数组来说,其初始有序数组元素个数为1,然后从第二个元素,插入到有序数组中。对于每一次插入操作,从后往前遍历当前有序数组,如果当前元素大于要插入的元素,则后移一位;如果当前元素小于或等于要插入的元素,则将要插入的元素插入到当前元素的下一位中。希尔排序先将整个待排序记录分割成若干子序列,然后分别进行直接插入排序,待整个序列中的记录基本有序时,在对全体记录进行一次直接插入排序...原创 2019-06-13 22:11:41 · 328 阅读 · 0 评论 -
继承
继承的概念:继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用class Person{public: void Print() { co...原创 2019-06-02 22:14:09 · 216 阅读 · 0 评论 -
多态
多态的概念通俗来说,就是多种形态,具体而言就是为了完成某一个行为,当不同的对象去完成时会产生不同的状态。举个栗子:同样是去景区游玩,但是在买票时却不一样——普通人买的时全价票,学生买的是半价票,军人是优先购票。多态的定义及实现多态定义的构成条件多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如Student继承了Person。Person对象买票全价,Student对象...原创 2019-06-03 23:18:55 · 222 阅读 · 0 评论 -
迭代器
迭代器Iterator(迭代器)模式又称Cursor(游标)模式,用于提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。或者这样说可能更容易理解:Iterator模式是运用于聚合对象的一种模式,通过运用该模式,使得我们可以在不知道对象内部表示的情况下,按照一定顺序(由iterator提供的方法)访问聚合对象中的各个元素。由于Iterator模式的以上特性:与聚合对象耦...原创 2019-06-11 23:09:57 · 429 阅读 · 0 评论 -
lambda表达式
在C++98中,如果想要对一个数据集合中的元素进行排序,可以使用std::sort方法。#include <algorithm> #include <functional> int main() { int array[] = {4,1,8,5,3,7,0,9,2,6}; // 默认按照小于比较,排出来结果是升序 std::sort(array, ...原创 2019-07-05 23:20:05 · 711 阅读 · 0 评论 -
变量类型推导
为什么需要类型推导在我们编程的时候会发现:在定义变量时必须先给出变量的实际类型编译器才会允许定义,但是有些情况可能不知道实际需要类型怎么给,或者类型写起来特别复杂#include <iostream>#include <map>#include <string>using namespace std;int main(){ short a = ...原创 2019-07-06 23:17:56 · 354 阅读 · 0 评论 -
异常
在C语言中,传统的错误处理机制是这样子的:终止程序,如****assert,缺陷:用户难以接受。如发生内存错误,除0错误时就会终止程序;返回错误码,缺陷:需要程序员自己去查找对应的错误。如系统的很多库的接口函数都是通过把错误码放到errno中,表示错误而大多数情况下,C语言都是通过返回错误码的方式来处理错误,部分情况下使用终止程序处理比较严重的错误。异常概念在C++中,提出了...原创 2019-07-27 13:35:02 · 492 阅读 · 0 评论 -
C++的类型转换
在C语言中,类型转换是这样子的void Test (){ int i = 1; // 隐式类型转换 double d = i; printf("%d, %.2f\n" , i, d); int* p = &i; // 显示的强制类型转换 int address = (int) p; printf("%x, %d\n" , p, address);}...原创 2019-08-09 14:25:59 · 314 阅读 · 1 评论 -
STL的内存优化
1)二级配置器结构STL内存管理使用二级内存配置器。1、第一级配置器第一级配置器以malloc(),free(),realloc()等C函数执行实际的内存配置、释放、重新配置等操作,并且能在内存需求不被满足的时候,调用一个指定的函数。一级空间配置器分配的是大于128字节的空间如果分配不成功,调用句柄释放一部分内存如果还不能分配成功,抛出异常2、第二级配置器在STL的第二级配置器...原创 2019-05-26 22:49:18 · 1102 阅读 · 2 评论 -
六一儿童节问题
题目描述六一儿童节,老师带了很多好吃的巧克力到幼儿园。每块巧克力j的重量为w[j],对于每个小朋友i,当他分到的巧克力大小达到h[i] (即w[j]>=h[i]),他才会上去表演节目。老师的目标是将巧克力分发给孩子们,使得最多的小孩上台表演。可以保证每个w[i]> 0且不能将多块巧克力分给一个孩子或将一块分给多个孩子。输入描述第一行:n,表示h数组元素个数第二行:n个h数组元...原创 2019-05-25 21:56:33 · 372 阅读 · 0 评论 -
STL之list类
list的介绍和使用list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效与其他的序列式容器相比(array,...原创 2019-05-16 23:24:20 · 412 阅读 · 0 评论 -
二叉搜索树
顾名思义,二叉搜索树是以一棵二叉树来组织的,这样的一棵树可以用一个链表结构来表示,每个节点除了data还有left、right、parent,分别指向节点的左孩子,右孩子和父节点。如果对应的节点不存在则指向NIL节点。(因为最简单的二叉搜索树中的NIL节点里并没有有用信息,所以在实现时简单的指向NULL也是可以的,本文中就会这么实现)二叉搜索树的性质若它的左子树不为空,则左子树上所有节点的值...原创 2019-04-21 23:53:43 · 260 阅读 · 0 评论 -
函数重载,重定义,重写
函数重载在一个类中声明多个名称相同但是参数列表不同的函数,这些的参数可能个数或顺序,类型不同,但是不能靠返回类型来判断,也就是说,在同一作用域中声明了名称相同,参数列表不同,返回值可以相同可以不同的函数。特征:相同的范围(在同一个作用域中)函数名字相同参数不同virtual 关键字可有可无(注:函数重载与有无virtual修饰无关)返回值可以不同;函数重写(覆盖)子类继承了父...原创 2019-05-03 15:17:26 · 375 阅读 · 0 评论 -
static关键字的作用
全局静态变量在全局变量前加上关键字static,全局变量就定义成一个全局静态变量.静态存储区,在整个程序运行期间一直存在。初始化:未经初始化的全局静态变量会被自动初始化为0(自动对象的值是任意的,除非他被显式初始化);作用域:全局静态变量在声明他的文件之外是不可见的,准确地说是从定义之处开始,到文件结尾。局部静态变量在局部变量之前加上关键字static,局部变量就成为一个局部静态变量。...原创 2019-05-04 23:04:22 · 827 阅读 · 0 评论 -
AVL树
上一篇所写的二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下。因此,两位俄罗斯的数学家G.M.Adelson-Velskii和E.M.Landis在1962年发明了一种解决上述问题的方法:当向二叉搜索树中插入新结点后,如果能保证每个结点的左右子树高度之差的绝对值不超过1(需要对树中的结点进行调整),即可降低树的高度,从而减...原创 2019-04-24 23:20:53 · 224 阅读 · 0 评论 -
C++中四种cast转换
C++中四种类型转换是:static_cast, dynamic_cast, const_cast, reinterpret_castconst_cast用于将const变量转为非conststatic_cast用于各种隐式转换,比如非const转const,void*转指针等, static_cast能用于多态向上转化,如果向下转能成功但是不安全,结果未知;dynamic_cast用...原创 2019-05-05 23:17:14 · 2218 阅读 · 0 评论 -
STL之string类
为什么要用string类在C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分割开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会造成越界访问。之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必担心内存是否足够、字符串长度等等,而且作为一个泛型类...原创 2019-05-13 22:41:16 · 188 阅读 · 0 评论 -
C++中的引用和指针
引用的定义:C++是C语言的继承,它可以进行过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计。引用就是C++对C语言的重要扩充。引用就是某一变量的一个别名,对引用的操作与对变量直接操作完全一样。引用的声明方法:类型标识符 & 引用名 = 目标变量名定义引用的表示方法与定义指针相似,只是用&代替了*引用的特性...原创 2019-05-06 21:35:42 · 350 阅读 · 0 评论 -
STL之vector类
vector的介绍vector是表示可变大小数组的序列容器就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效,但是又不像数组一样,它的大小是可以动态改变的,而且它的大小会被容器自动处理本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时,这个数组需要被重新分配大小来增加存储空间。其做法是,分配一个新的...原创 2019-05-14 12:46:09 · 276 阅读 · 0 评论 -
vector与list的区别
概念:vector连续存储的容器,动态数组,在堆上分配空间底层实现:数组两倍容量增长:vector 增加(插入)新元素时,如果未超过当时的容量,则还有剩余空间,那么直接添加到最后(插入指定位置),然后调整迭代器。如果没有剩余空间了,则会重新配置原有元素个数的两倍空间,然后将原空间元素通过复制的方式初始化新空间,再向新空间增加元素,最后析构并释放原空间,之前的迭代器会失效。性能:访问...原创 2019-05-19 23:09:32 · 1320 阅读 · 0 评论 -
结构体对齐规则
为什么要进行内存对齐#include <iostream>using namespace std;struct A{ char a; int b; short c;};struct B{ short c; char a; int b;};int main(){ cout << sizeof(A) << end...原创 2019-05-09 22:18:36 · 551 阅读 · 0 评论 -
类和对象经典面试题(一)
定位new表达式在已分配的原始内存空间中调用构造函数初始化一个对象格式:new(place_address) type 或者new(place_address) type(initializer_list)其中place_address必须是一个指针,initializer_list是类型的初始化列表使用场景:一般配合内存池使用,因为内存池分配出的内存没有初始化,所以如果是自定义类型的...原创 2019-05-10 12:39:10 · 850 阅读 · 0 评论 -
简单实现string类以及深浅拷贝问题
对象之间可以进行复制操作,包括采用拷贝构造函数的方式用一个对象去构造另一个对象(用一个对象的值初始化一个新的构造的对象),如同指针的复制一样,对象复制也分为浅复制和深复制对象浅拷贝:两个对象之间进行复制时,若复制完成后,他们还共同使用着某些资源(内存空间),其中一个对象的销毁会影响另一个对象(动态顺序表)如果没有显式提供拷贝构造函数与赋值运算符重载,编译器会生成一个默认的拷贝构造函数和运算符...原创 2019-05-15 22:13:37 · 321 阅读 · 0 评论 -
单例模式
单例模式就是保证一个类只有一个实例,并提供一个访问它的全局访问点。首先,需要保证一个类只有一个实例;在类中,要构造一个实例,就必须调用类的构造函数,如此,为了防止在外部调用类的构造函数而构造实例,需要将构造函数的访问权限标记为protected或private;最后,需要提供要给全局访问点,就需要在类中定义一个static函数,返回在类内部唯一构造的实例饿汉模式程序启动时就创建一个唯一的实例对...原创 2019-05-11 18:15:39 · 174 阅读 · 0 评论 -
STL中list类的模拟实现
#include <iostream>using namespace std;//结点的定义template <class T>struct Node {public: Node(const T& data = T()) :data_(data) ,prev_(nullptr) //指向前驱结点 ,next_(nullptr) //指向...原创 2019-08-17 14:20:40 · 239 阅读 · 0 评论