C++
文章平均质量分 69
午饭要阳光
热爱编程
展开
-
new、delete与malloc、free
一、new和delete 程序运行时,计算机的内存被分为4个区域:程序代码区,全程数据区,栈和堆。其中堆上的内存可以被用户自由分配和释放。C语言中提供了malloc(还有calloc和realloc)和free函数来进行动态内存管理。C++中则提供了new和delete运算符来进行动态内存管理。因为new和delete是运算符,所以性能要更高效(没有函数调用时的开销),使用更灵活。原创 2016-07-21 18:18:16 · 1568 阅读 · 0 评论 -
String的实现
String类的简单实现:1、在拷贝构造函数和赋值运算符重载这两个函数中有浅拷贝和深拷贝的问题2、要对输入输出函数重载3、赋值运算符重载有两种方式。注意在采用交换实现的时候函数的参数只能是临时变量class String{ friend ostream& operator<<(ostream& os, String& s); friend istream& opera原创 2016-08-23 12:41:03 · 1124 阅读 · 0 评论 -
字符串类型解读
C++中提供了一种新的数据类型——字符串类型(string)。实际上string并不是C++的基本类型,它是在C++标准库中声明的一个字符串类,用这种数据类型可以定义对象,每一个字符串变量都是string类的一个对象。一、字符串类型:string 字符串类包含在头文件#include中,因此使用string时必须包含头文件#include。字符串变量必须先定义后使用,定义字符串变原创 2016-08-09 23:34:40 · 942 阅读 · 0 评论 -
多态性与虚函数
一、什么是多态 C++有三大特性,封装、继承、多态。多态是面向对象程序设计的一个重要特征。利用多态性可以设计和实现一个易于扩展的系统。多态就是一个事物有多重状态,在C++程序设计中,多态性是指具有不同功能的函数可以用一个函数名,这样就可以用同一个函数名实现不同的功能。 从系统的角度看,多态分为静态多态和动态多态。静态多态是利用重载实现的,在程序编译时确定要调用的是哪个函数,因此静态多态原创 2016-07-24 15:49:55 · 1729 阅读 · 0 评论 -
继承和派生
一、什么是继承和派生 封装、继承、多态是C++的三个重要的特性。在面向对象的技术中强调软件的可重用性,而继承机制就是用来解决软件的重用问题。在C++中,所谓“继承”就是在一个已经存在的类的基础上建立一个新的类。已经存在的类成为基类或父类,新建立的类称为派生类或子类。 一个类从一个已有的类那里获得已有的特性,这种现象称为类的继承。通过继承,一个新建的子类从父类那里获得父类的特性。从另一角原创 2016-07-22 17:05:36 · 1816 阅读 · 0 评论 -
浅拷贝和深拷贝
一、浅拷贝和深拷贝 所谓浅拷贝,就是由默认的拷贝构造函数所实现的对数据成员逐一赋值。若类中含有指针类型的数据,这种方式只是简单的把指针的指向赋值给新成员,但并没有给新成员分配内存,因此这种方式必然会导致错误。为了解决浅拷贝出现的错误,必须显示的定义一个拷贝构造函数,使之不但复制数据成员,而且为对象分配各自的内存空间,这就是所谓的深拷贝。二、浅拷贝 浅拷贝就是由默认的拷贝构造原创 2016-07-21 18:23:03 · 1900 阅读 · 0 评论 -
set与map用法简介
在介绍容器之前,我们先来介绍一下pair,pair是一种模板类型,每个pair可以存储两个值,这两个值的类型可以是任何类型的。它定义在#include 中。可以看到,pair的两个成员分别是first和second。一、set(集合): set是一种key结构,它的元素就是它的键值,set不允许有两个相同的键值,set中的所有元素的键值都会自动被排序。set和原创 2016-11-13 18:58:37 · 1084 阅读 · 1 评论 -
如何定义一个不能被继承的类
如何定义一个不能被继承的类??? 假设有一个类B,如果把B的构造函数声明为私有的,那么B这个类就不能被继承,但是这也引入了一个问题,不能在类外定义B类型的对象,那要怎么解决这个问题呢???方法1: 我们可以在类内创建一个对象并提供一个静态的接口,返回创建的这个对象。但是如果使用这种方法的话,在定义B的对象的时候感觉不是很完美。方法2:原创 2016-11-08 21:19:41 · 3922 阅读 · 0 评论 -
如何定义一个只能在堆上生成对象的类
如何定义定义一个只能在堆上生成对象的类???这种题主要考的是对C++语法的理解,以及对C++语法的运用。分析: 对象可以在栈上生成也可以由我们在堆上new出来。要想只在堆上生成对象而不能在栈上生成对象在类外是无法完成的,我们必须从类的内部入手。 我们知道类对象的构造是由构造函数完成的,如果我们把构造函数声明为保护的,使得不能在类外调用构造原创 2016-11-08 19:08:47 · 1249 阅读 · 0 评论 -
如何定义一个只能在栈上生成对象的类
如何定义定义一个只能在栈上生成对象的类??? 这种题主要考的是对C++语法的理解,以及对C++语法的运用。分析: 对象可以在栈上生成也可以由我们在堆上new出来。要想只在栈上生成对象而不能在堆上生成对象在类外是无法完成的,我们必须从类的内部入手。 我们知道类对象的构造是由构造函数完成的,如果我们把构造函数声明为保护的,使得不能在类外原创 2016-11-08 19:13:11 · 1048 阅读 · 0 评论 -
STL——总纲
STL(标准模板库)是C++标准库中最重要的组成部分,它不仅是一个可复用组件库,而且是一个包罗算法和数据结构的软件空间。 STL充分体现了泛型化思想,它致力于追求复用。在复用的同时,STL还追求效率,比如迭代器萃取机制。总的来说,STL所做的一切都是以复用和效率为目标的。 STL有多个版本,linux下面用的SGI版,windows下面的PJ版。此外还有HP版本、RW版本等。原创 2016-12-19 16:17:25 · 706 阅读 · 0 评论 -
揭秘——STL空间配置器
为什么要有空间配置器呢?这主要是从两个方面来考虑的。1、小块内存带来的内存碎片问题 单从分配的角度来看。由于频繁分配、释放小块内存容易在堆中造成外碎片(极端情况下就是堆中空闲的内存总量满足一个请求,但是这些空闲的块都不连续,导致任何一个单独的空闲的块都无法满足这个请求)。2、小块内存频繁申请释放带来的性能问题。 关于性能这个问题要是再深究起来还是比较原创 2016-12-07 23:07:10 · 5098 阅读 · 0 评论 -
C++实现五子棋游戏
三子棋、五子棋之类的游戏,非常简单,对于初学者来说是一个不错的练手的小项目,以前用C语言写过三子棋游戏。最近在看C++,所以就想到在三子棋的基础上利用C++语言实现五子棋游戏。主要功能: 有3个模式:0表示退出、1表示电脑vs玩家、2表示玩家vs玩家。 当一局完成之后选择’y’则又会进入选择模式。 源代码(VS2013编译器下写的):#include<iostream>#include<st原创 2017-01-23 11:45:14 · 32938 阅读 · 9 评论 -
C++知识体系结构框图
喜欢这张图的发送 “C++知识体系框图” 到 “[email protected]”,会发送给给你。原创 2016-09-04 20:43:52 · 6304 阅读 · 2 评论 -
大数运算
一、为什么要有大数运算 在C/C++编程语言中,整型的最大存储类型是long long类型,大小是8个字节,一但超出这个范围,则就无法用编程语言的内置类型存储。因为编程语言的存储范围有限,所以它不能满足较大规模的高精度的计算,于是就产生了大数运算这种方法。二、大数运算原理 由于内置类型的存储范围有限,所以我们可以将大数转换成字符串存储在数组里面,然后再对每一位做单独的加减乘除运原创 2017-05-31 18:47:14 · 1759 阅读 · 0 评论 -
LRU缓存策略设计
一、什么是LRU缓存策略 LRU(Least Recently Used)近期最少使用算法。它的原理就是,缓存一定量的数据,当缓存数量超过设置的阈值时就删除一部分旧的数据。 那么我们怎样判定旧数据呢???根据局部性原理,距离当前最久没有被访问过的数据应该被淘汰。二、LRU缓存策略实现原理 1、使用双向链表记录数据的被使用的时间 因为我们要删除最久没有被访问的数据原创 2017-06-02 11:53:28 · 1802 阅读 · 2 评论 -
深入C++对象模型&虚函数表
多态的实现机制: C++中虚函数的主要作用就是用来实现多态,就是使用基类的指针或者引用调用重写的虚函数,当父类的指针或引用指向父类对象时调用的是父类虚函数,当指向子类对象时调用的是子类的虚函数。那么这又是怎么实现的呢??? 这都是通过虚函数表实现的,虚函数表是通过一块连续内存来存储虚函数的地址。这张表解决了虚函数重写(地址进行覆盖)的问题 。在有虚函数的对象实例中都原创 2016-08-25 09:40:37 · 1664 阅读 · 2 评论 -
写时拷贝
Copy On Write(COW):写时拷贝技术一、什么是写时拷贝技术:写时拷贝技术可以理解为“写的时候才去分配空间”,这实际上是一种拖延战术。举个栗子:二、写时拷贝技术原理: 写时拷贝技术是通过"引用计数"实现的,在分配空间的时候多分配4个字节,用来记录有多少个指针指向块空间,当有新的指针指向这块空间时,引用计数加一,当要释放这块空间时,引用计原创 2016-08-29 17:05:49 · 2050 阅读 · 1 评论 -
重载、重写、隐藏
重载:1、在同一作用域中 2、函数名相同、参数个数或参数类型不同,返回值可同可不同 重载又称为静态多态,静态绑定,静态决议等。因为要实现重载,所以C++和C的命名方式有所不同。重载主要是为了减轻程序员对函数名的记忆负担,让所有功能相似的函数使用同一名字。隐藏:1、在不同作用域中,分别在基类和派生类中 2、隐藏只要求函数名相同就行 3、在派生类中只要不原创 2016-08-29 17:55:50 · 1130 阅读 · 0 评论 -
类默认生成的成员函数
类默认生成的六个成员函数一、构造函数 我们知道,类的数据成员是不能在声明类的时候初始化的,因为类并不是一个实体,而是一种抽象的数据类型,并不占据存储空间。为了解决这个问题,C++提供了构造函数来处理对象的初始化。1、构造函数的作用 构造函数是一种特殊的成员函数,与其他成员函数不同,构造函数是在对象被实例化的时候自动被调用的,而且只执行这一次,它不能被用户调原创 2016-07-19 17:18:12 · 2295 阅读 · 2 评论 -
静态成员
一、静态数据成员静态数据成员是一种特殊的数据成员,它以关键字static开头。例:声明一个长方体类classBox{public: Box(int length = 0, int width = 0) :_length( length) , _width(原创 2016-07-19 12:25:47 · 1607 阅读 · 0 评论 -
解析内联函数
一、什么是内联函数?为什么使用内联函数?调用函数是需要一定的时间和空间的开销的。 上图表示函数调用的过程,1程序执行函数调用前的语句;2流程的控制转移到被调用函数的入口处,同时进行参数传递;3执行被调用函数中函数体语句;4流程返回到调用函数的下一条指令处,将函数返回值带回;5接着执行主调函数中未执行的部分。 在2执行之前,要记下当时指令的地址还要“保护现场”(记下当时有关的原创 2016-07-19 09:40:53 · 1461 阅读 · 0 评论 -
不同类型数据间的转换
对于标准数据类型的转换,编译系统有章可循,知道怎样进行转换。而对用户自己声明的类型,编译系统并不知道怎样进行转换,解决这个问题的关键是让编译系统知道怎样去进行折现转换,需要定义一些专门的函数类处理。1、转换构造函数 转换构造函数的作用是将一个其它类型的数据转换成一个类的对象以复数类Complex为例,我们来介绍一下 转换构造函数。转换构造函数是构造函数的重载,它只有一个形参,原创 2016-07-18 21:10:49 · 2328 阅读 · 0 评论 -
类模板
对于功能相同而数据类型不同的一些类,我们不必重复定义,可以定义一个可对任何类型变量进行操作的类模板(template)。例:定义一个比较大小的类template //声明一个类模板,template是关键字,虚拟类型是datatypeclass Compare{public: Compare(datatype x=0, datatype y=0) :_x(x) //原创 2016-07-18 19:27:54 · 2551 阅读 · 0 评论 -
运算符重载
一、什么是运算符重载 我们知道函数重载就是对已有的函数赋予新的含义,使之实现新的功能。因此,同一个函数可以实现不同的功能,也就是一名多用。 运算符也可以重载,像我们平时使用的+运算符,对整形,单精度浮点型,双精度浮点型都能实现加法运算。又如,>(右移),在输入操作中与流对象cin配合使用实现输入操作。 在C++程序中,用户不能直接用C++提供的运算符来实现用户自定义类的运算,所以原创 2016-07-18 18:04:00 · 1870 阅读 · 1 评论 -
深入理解命名空间
一、为什么使用命名空间 一个大型的工程往往是由若干个人独立完成的,不同的人分别完成不同的部分,最后再组合成一个完整的程序。由于各个头文件是由不同的人设计的,有可能在不同的头文件中用了相同的名字来命名所定义的类或函数,这样在程序中就会出现名字冲突。不仅如此,有可能我们自己定义的名字会与C++库中的名字发生冲突。 名字冲突就是在同一个作用域中有两个或多个同名的实体,为了解决命名冲突 ,原创 2016-07-17 09:31:44 · 18545 阅读 · 3 评论 -
指针和引用
一、什么是引用??? "引用"是C++中引入的新的变量类型,它的作用是为一个变量起一个别名。引用的使用形式如下: 类型 &引用变量名=已定义过的变量名; 例如:int a=10; int &b=a; b是a的引用,即b是a的别名,a和b的作用相同。对a所进行的操作的结果与对b所进行的操作结果是完全相同的。声明b为引用类型并不需要为b另外开辟空间原创 2016-07-10 00:34:57 · 1899 阅读 · 0 评论 -
解析this指针
要想明白为什么有this指针,我们先来看一看数据成员与成员函数之间的关系 每个对象中的数据成员都占有存储空间,如果一个类定义了n个对象的话,那么就有n个大小相等的空间来存放这n个对象的数据成员,但是不同的对象都调用同一个代码段。 那么问题来了!!! 当不同对象的成员函数引用数据成员时,怎么能够保证引用的是所指定的对象的数据成员呢?例如:设计一个长方体类原创 2016-07-09 14:53:49 · 1947 阅读 · 1 评论 -
函数重载
1、什么是函数重载??? 在同一个作用域中,如果有多个函数的名字相同,但是形参列表不同(参数类型不同或参数个数不同),返回值类型可同也可不同,我们称之为重载函数。重载的函数是通过形参列表区分的,与返回值类型无关。函数重载其实是"一个名字,多种用法"的思想,不仅函数可以重载,运算符也可以重载。例如:现在要实现一个加法运算,运算子可以是整形也可以是浮点型,就可以通过重载实现。intAD原创 2016-06-27 17:27:58 · 23256 阅读 · 0 评论 -
强制类型转换
C++中的强制类型转换:static_cast、reinterpret_cast、const_cast、dynamic_cast.static_cast:用于非多态类型之间的转换(静态转换),任何标准类型之间都可以用它,但它不能用于不相关类型之间的转换。static_cast只能用于相关类型之间的转换。例: int i = 2; double d = static原创 2016-09-04 20:28:11 · 912 阅读 · 0 评论 -
类型萃取
在C++中我们可以通过typeid来获取一个类型的名称(内置类型和自定义类型都可以),但是我们不能用这种方式获取来的名称做变量的声明。那么在C++中怎样识别对象的类型呢??我们可以通过类型萃取的方式来区分内置类型和自定义类型。 例如:我们在Seqlist中要用到类型萃取,因为内置类型我们可以通过memcopy和memmove这两个方式进行拷贝,自定义类型或string我们要通过赋值的方式拷贝原创 2016-09-04 20:25:59 · 1154 阅读 · 0 评论 -
shared_ptr之循环引用&定置删除器
shared_ptr虽然方便,但是它有着一个致命的缺陷就是循环引用问题,因为shared_ptr本身并没有能力解决这个问题,所以我们又引入了弱指针weak_ptr来辅助shared_ptr解决这个问题。那么循环引用又是什么场景?举个栗子:假设现在我们要创建一个双向整形链表,但是这个链表的指针域全部都用shared_ptr维护:struct Node{ int原创 2016-09-04 10:31:19 · 2650 阅读 · 0 评论 -
解析智能指针底层简单实现
很多人都误以为智能指针是一个指针,其实不然,智能指针不是指针,智能指针是一个模板,由智能指针实例化出来的的对象具有和常规指针相似的行为,但是他能够自动的释放所指向的对象,所以我们称之为智能指针。如果我们用普通指针来创建一个指向某个对象的指针,那么我们最后必须要手动释放这块空间,而智能指针它是一个类,它释放空间是通过析构函数完成的,正是由于有了这一层封装机制,所以智能指针才能够管理一个对象的生命周期原创 2016-09-03 10:58:13 · 3087 阅读 · 0 评论 -
new/delete和new[]/delete[]的底层调用和简单实现
在使用new的时候做了两件事:1、调用operator new分配空间2、调用构造函数初始化对象在使用delete的时候也做了两件事:1、调用析构函数清理对象2、调用operator delete函数释放空间在使用new[N]的时候也做了两件事:1、调用operator new分配空间2、调用N次构造函数初始化N个对象在使用delete[原创 2016-08-30 16:12:28 · 1280 阅读 · 0 评论 -
STL之set相关算法
STL一共提供了四种set相关的算法,分别是并集(union),交集(intersection),差集(difference),和对称差集(symmetric difference)。 STL的这四个算法所接受的set必须是有序区间,元素可以重复出现。即他们只能接受set/multiset容器作为输入区间。 1、set_unoin(求并集) 算法set_union可构造两个S1,S2这原创 2017-07-06 21:53:41 · 1333 阅读 · 0 评论