C/C++
文章平均质量分 52
蓝旭晨枫
无论这个世界对你怎样,都请你一如既往的努力、勇敢、充满希望
展开
-
构造/析构/赋值 函数
条款10:令operator=返回一个reference to *this赋值操作符运算是由右向左运算的。例如一个连锁赋值[cpp] view plain copy "font-size:14px;">int x, y, z; x=y=z=15; 编译器解释时时这样的:x=(y=(z=15));先给z赋转载 2016-04-10 22:40:29 · 356 阅读 · 0 评论 -
C++命名空间
1、内联命名空间内联命名空间中的名字可以被外层命名空间直接使用,无需命名空间前缀访问它的成员。使用场景:当应用程序的不同版本共存时,可以将当前最新版本放在内联命名空间中,而把所有的旧版本放在非内联命名空间中。2、未命名的命名空间(1)未命名命名空间中定义的变量拥有静态生命周期:它们在第一次使用前创建,并且直到程序结束才销毁。(2)一个未命名的命名空间在一个给定的文件内可原创 2016-04-07 22:15:19 · 399 阅读 · 0 评论 -
list不能使用STL算法sort()
原创 2016-04-07 22:18:32 · 910 阅读 · 0 评论 -
lower_bound()函数和upper_bound()函数
1、lower_bound()函数在不破坏排序状态的原则下,可插入value的第一个位置templateForwardIt lower_bound(ForwardIt first, ForwardIt last, const T& value){ ForwardIt it; typename std::iterator_traits::difference_type c原创 2016-04-07 19:11:51 · 427 阅读 · 0 评论 -
哈希表处理冲突的方法
哈希表处理冲突的方法在哈希表中处理冲突的方法“1、线性探测冲突发生时,顺序查看表中下一个单元,直到找出一个空闲的单元或查遍全表。2、二次哈希当di=1^2,-1^2,2^2,-2^2,...,k^2,-k^2二次探测法是一种比较好的处理冲突的方法。可以避免出现堆积的问题。缺点是不能探测到散列表中的所有单元,但至少能探测到一半的单元。原创 2016-04-07 18:49:37 · 3665 阅读 · 0 评论 -
C++内存分配方式
C++中内存的分配方式和分配区域.堆、栈、静态存储区.堆(heap):由程序员分配,new和delete。它们的释放编译器不管,由应用程序控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。堆可以动态地扩展和收缩。栈(stack):就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区域。里面的变转载 2016-04-05 13:41:22 · 384 阅读 · 0 评论 -
STL六大组件
STL六大组件发表于 2015 年 6 月 1 日1、容器(containers)如vector、list、deque、set、map用来存放数据。从实现的角度看,STL容器是一种类模板。2、算法(algorithms)如sort、search、copy、erase。从实现角度看,STL算法是一种函数模板。3、迭代器(iterator原创 2016-04-07 13:46:39 · 419 阅读 · 0 评论 -
STL序列式容器 - heap
STL 源码剖析之四:序列式容器---heapSTL- heap主要有以下几种操作组成:make_heap,建堆sort_heap,堆排序pop_heap,取出堆顶元素push_heap,调整堆heap并不归属于STL容器组件,它是个幕后英雄,扮演priority queue的助手。binary max heap适合作为priorit原创 2016-04-07 14:02:10 · 382 阅读 · 0 评论 -
STL序列式容器 - deque
STL 序列式容器 - dequedeque是一种双向开口的连续线性空间。所谓双向开口,意思就是可以头尾两端分别做元素的插入和删除操作。当然,vector也可以在头尾两端进行插入删除操作(从技术上讲),但是其头部操作效率极差,无法被接受。deque相比vector差异:1、deque允许于常数时间内对头端进行元素的插入和删除操作。2、deque没原创 2016-04-07 13:58:19 · 487 阅读 · 0 评论 -
深入学习STL第二级配置器
深入学习STL第二级配置器相比第一级配置器,第二级配置器多了一些机制,避免小额区块造成内存的碎片。不仅仅是碎片的问题,配置时的额外负担也是一个大问题。因为区块越小,额外负担所占的比例就越大。额外负担是指动态分配内存块的时候,位于其头部的额外信息,包括记录内存块大小的信息以及内存保护区(判断是否越界)。1、SGI STL第二级配置器具体实现思想如下:原创 2016-04-07 13:53:25 · 708 阅读 · 1 评论 -
SGI特殊的空间配置器 std::alloc
SGI特殊的空间配置器 std::alloc1、一般而言,我们所习惯的C++内存配置操作和释放操作是这样的:class Foo{ Foo *pf = new Foo; delete pf;}; 这其中的new实际上包含两个阶段操作:(1)new表达式调用一个,名为::operator new(或者::operator new[原创 2016-04-07 13:48:29 · 340 阅读 · 0 评论 -
关联式容器set和map原理
1、标准的STL关联式容器分为set(集合)和map(映射表)两大类,以及这两大类衍生而来的multiset(多键集合)和multimap(多键映射表)。2、这些容器的底层均以RB-tree(红黑树)完成。RB-tree(红黑树)也是一个独立的容器,但并不开放给外界使用。3、此外,SGI STL还提供了一个不在标准规格之列的关联式容器:hash table(散列表),以及以原创 2016-04-07 13:44:38 · 624 阅读 · 0 评论 -
STL笔记之hashtable
STL笔记之hashtable程序人生 2014-08-24 1020 阅读stl之前对hash一直存在恐惧感,毕竟没用过……最近在一个组件里面自己实现了一个hashtable,感觉也就这么回事;回头看看书上对hashtable的分析,发现是极其的相似。不过,旧版本的C++标准里面并没有hashtable这个东西,而C++11中引入了相关的容器(std::unordered转载 2016-04-10 10:46:17 · 301 阅读 · 0 评论 -
STL笔记之优先队列
STL笔记之优先队列程序人生 2014-07-05 95 阅读堆 stl在STL中队列queue是基于deque实现的,优先队列priority_queue则是基于堆实现的。所谓优先队列即元素具有优先级的队列,在最大优先级队列中,队列最前面的元素具有最高的优先级,最大优先级队列基于最大堆(max-heap)实现。1. 堆的基本性质二叉堆是一颗完全二叉树,可以分为转载 2016-04-10 10:47:44 · 329 阅读 · 0 评论 -
《STL源码剖析》---stl_hashtable.h阅读笔记
在前面介绍的RB-tree红黑树中,可以看出红黑树的插入、查找、删除的平均时间复杂度为O(nlogn)。但这是基于一个假设:输入数据具有随机性。而哈希表/散列表hash table在插入、删除、查找上具有“平均常数时间复杂度”O(1);且不依赖输入数据的随机性。hash table的实现有线性探测、二次探测、二次散列等实现,SGI的STL是采用开链法(separate chaining)来转载 2016-04-10 10:51:18 · 523 阅读 · 0 评论 -
以对象管理资源、在资源管理类中小心coping行为、在资源管理类中提供对原始资源的访问
在系统中,资源是有限的,一旦用完必须归还给系统,否则可能会造成资源耗尽或其他问题。例如,动态分配的内存如果用完不释放会造成内存泄漏。这里说的资源不仅仅是指内存,还包括其他,例如文件描述符、网络连接、数据库连接、互斥锁等。在任何情况下都要把不使用的资源归还系统是一件非常困难的事情。尤其是考虑到异常、函数内多重回传路径等。基于对象的资源管理办法几乎可以消除资源管理的问题。下面介转载 2016-04-10 22:33:26 · 331 阅读 · 0 评论 -
考虑写出一个不抛出异常的swap函数
条款25:考虑写出一个不抛出异常的swap函数swap是STL中的标准函数,用于交换两个对象的数值。后来swap成为异常安全编程(exception-safe programming,条款29)的脊柱,也是实现自我赋值(条款11)的一个常见机制。swap的实现如下:namespace std{ templatetypename T> void swap(T& a, T&原创 2016-04-10 22:25:06 · 473 阅读 · 0 评论 -
了解typename的双重意义
使用模板时,可以用typename,也可以用class templateclass T> class Widget; templatetypename T> class Widget;12两者没有什么不同。作为template的类型参数,意义完全相同。在使用习惯上来说,很多人喜欢使用typename,因为这暗示参数并非一定要是个class类型。C++有时不会把class原创 2016-04-10 22:17:27 · 539 阅读 · 0 评论 -
进程创建
1、许多其它操作系统提供spawn产生进程的机制。而Unix采用与众不同的方式,它把上述步骤分解到两个单独的函数中去执行:fork()和exec()。首先,fork()通过拷贝当前进程创建一个子进程、子进程与父进程的唯一区别就在一进程ID。PID、PPID(父进程进程号)exec()函数负责读取可执行文件并将其载入地址空间开始运行。2原创 2016-04-10 22:13:13 · 418 阅读 · 0 评论 -
Linux中getopt()函数用法
1、getopt()2、getopt_long()下面来讲getopt_long函数,getopt_long函数包含了getopt函数的功能,并且还可以指定“长参数”(或者说长选项),与getopt函数对比,getopt_long比其多了两个参数: int getopt(int argc, char * const argv[],原创 2016-04-10 22:10:22 · 1281 阅读 · 0 评论 -
C++深拷贝与浅拷贝的区别
转自:http://blog.csdn.net/sghcpt/article/details/5578320又加了一些自己补充。原文:Memberwise copy: 在初始化一个对象期间,基类的构造函数被调用,成员变量被调用,如果它们有构造函数的时候,它们的构造函数被调用,这个过程是一个递归的过程.Bitwise copy: 原内存拷贝.例子,给定一个对象ob转载 2016-04-10 20:57:51 · 427 阅读 · 0 评论 -
C语言str函数系列
1、strcat()此函数原型为 char *strcat(char *dest, const char *src).功能为连接两个字符串,把src连接到dest后面;返回dest地址实现如下[cpp] view plain copy char * strcat(char *dest,const char *src)转载 2016-04-10 20:55:11 · 504 阅读 · 0 评论 -
C++中的智能指针
当设计含有指针的类时,应特别小心。因为指针指向的对象通常不包含在类的对象中,当类对象进行复制时,默认复制构造函数通常是浅拷贝(bitwise copy),只是拷贝了指针的值,这是两个指针指向同一个对象。通过其中一个指针就可以改变对象的值,也可以释放指针指向的对象;这时候另一个指针并不知情。引用C++ Primer的例子[cpp] view plain copy转载 2016-04-10 20:54:33 · 309 阅读 · 0 评论 -
句柄类中计数器的分离
句柄类是管理基类指针的类,“智能指针”的类其实就是句柄类。智能指针都有一个对应的计数器,这个计数器可以在智能指针指向的对象中,在“C++中的智能指针”中就是这样的;也可以在句柄类中。这两种有一些区别。当计数器在智能指针对象的内部时,我们需要在类的外层加一层包装,之前用Ptr类,但是为了用计数器,在类Ptr外层包装了U_Ptr类。如下图:其实还可以计数器和指针对象的分离,转载 2016-04-10 20:44:59 · 399 阅读 · 0 评论 -
C/C++中volatile关键字
1. volatile关键字C/C++ 中的 volatile 关键字和 const 对应,用来修饰变量,通常用于建立语言级别的 memory barrier。这是 BS 在 "The C++ Programming Language" 对 volatile 修饰词的说明:A volatile specifier is a hint to a compiler that an ob转载 2016-04-10 20:40:20 · 253 阅读 · 0 评论 -
do{}while(0)在宏定义中的作用
在开源代码中看到,宏定义经常这样用[cpp] view plain copy #define some() do { do_somt_thing(); } while (0) 为什么这样用转载 2016-04-10 20:34:07 · 289 阅读 · 0 评论 -
虚函数能否是内联函数
内联函数是在编译时,将调用函数处插入内联函数的代码,省去了函数调用时的开销。虚函数是通过指针或引用调用函数时,通过虚函数表来确定调用的函数,在运行时确定。那么虚函数是否可以是内联函数?以前没有想过这个问题,表面上看,虚函数不能为内联函数。我们在类中定义的函数都是内联函数,析构函数经常在类中定义,而析构函数又经常声明为虚函数,以前没有发现什么问题。其实虚函数可以为内联函数,这转载 2016-04-10 20:29:56 · 569 阅读 · 0 评论 -
关联式容器map/multimap
和set相比,map同时拥有实值(value)和键值(key),其每一个元素都是pair,pair的第一个元素是键值,第二个元素是实值。map和multimap的区别在于,map不允许两个元素拥有相同的键值,而multimap允许存在重复的键值。pairpair定义如下:123456789t原创 2016-04-07 13:43:41 · 325 阅读 · 0 评论 -
关联式容器set/multiset
1、set的特性是,所有元素都会根据元素的键值自动排序。set的元素不像map那样可以同时拥有实值(value)和键值(key),set元素的键值就是实值,实值就是键值。set不允许两个元素有相同的键值。2、不能通过set的迭代器改变set的元素值。因为set元素值就是其键值,关系到元素的排列规则。如果任意改变set的元素值,会严重破坏set组织。(因为底层是用平衡二叉搜索树完成的,如原创 2016-04-07 13:42:36 · 350 阅读 · 0 评论 -
线程安全和不可重入
线程安全问题都是由全局变量和静态变量引起的可重入函数是线程安全函数的子集可重入的要求:不使用、不返回任何非常量的全局或者静态变量,也不调用任何不可重入函数。它可以被中断,意味着它除了使用自己栈上的变量不依赖于任何环境(包括static),这样的函数就是purecode(纯代码)可重入。可以允许有多个函数的副本在同时运行,因为它们使用的是分离的栈,不会互相干扰。但是对于不原创 2016-04-07 13:39:27 · 493 阅读 · 0 评论 -
C++ lambda表达式
lambda表达式一个lambda表达式表示一个可调用的代码单元。我们可以将其理解为一个未命名的内联函数。一个lambda表达式具有一个返回类型、一个参数列表、一个函数体。但与函数不同,lambda表达式可定义在函数内部。一个lambda表达式具有如下形式:[capture list] (parameter list) -> return type { funct原创 2016-04-05 18:35:25 · 269 阅读 · 0 评论 -
register关键字,valatile关键字
register关键字,valatile关键字一、register例子register修饰符暗示编译程序相应的变量将被频繁地使用,如果可能的话,应将其保存在CPU的寄存器中,以加快其存储速度。例如下面的内存块拷贝代码,12345678910#ifdef NOS原创 2016-04-05 18:34:05 · 446 阅读 · 0 评论 -
C++强制类型转化
1、static_cast任何只要具有明确定义的类型转换,只要不包含底层const就可以使用static_cast当需要把一个较大的算数类型赋值给一个较小的算数类型,static_cast非常有用。此时,强制类型转换告诉程序的读者和编译器:我们不在乎潜在的精度损失。一般来说,如果编译器发现一个较大算数类型试图赋值给一个较小的类型,会给出警告信息,但是我们执行了显式的类型转换后警告信原创 2016-04-05 18:31:16 · 435 阅读 · 0 评论 -
多维数组和指针
1、当程序使用多维数组的名字时,也会自动将其转换为指向数组首元素的指针。 定义指向多维数组的指针时,千万别忘了这个多维数组实际上是数组的数组。2、因为多维数组实际上是数组的数组,所以由多维数组名转换而来的指针实际上是指向第一个内层数组的指针: int ia[3][4]; // 大小为3 的数组,每个元素是含有4个整数的数原创 2016-04-05 18:30:15 · 296 阅读 · 0 评论 -
C++虚析构函数的作用
当我们delete一个动态分配的对象的指针时将执行析构函数。如果该指针指向继承体系中的某个类型,则有可能出现指针的静态类型与被删除对象的动态类型不符的情况。例如,当我们delete一个基类类型的指针,则该指针有可能指向的是一个派生类类型的对象,如果这样的话编译器就必须清楚它应该执行派生类的析构函数总而言之,如果基类的析构函数不是虚函数,则delete一个指向派生原创 2016-04-05 18:26:47 · 295 阅读 · 0 评论 -
C++的new和delete工作机理
1、当使用一条new表达式时,实际上执行了三个步骤: string *sp = new string("value");string *arr = new string[10]; 1)new表达式调用一个名为operator new(或者operator new[])的标准库函数,该函数分配一块足够大的、原始的、未命名的内存空间以便存储特定类型的对象。原创 2016-04-05 18:22:11 · 321 阅读 · 0 评论 -
隐式的类类型转换
开头:内置类型之间有自动转换规则,我们也能为类类型定义隐式转换规则。如果构造函数只接受一个实参,则它实际上定义了一个从构造函数参数类型向此类类型的隐式转换机制有时我们把这种构造函数称为转换构造函数,但是1、只允许一步类类型转换//错误:需要用户定义的两种转换://(1)从“9-999-9999-9” 转换成string//(2)从string原创 2016-04-05 18:17:03 · 402 阅读 · 0 评论 -
memset 、ZeroMemory和 “={0}” 三者区别
memset是以字节为单位,初始化内存块。当初始化一个字节单位的数组时,可以用memset把每个数组单元初始化成任何你想要的值,比如char data[10]; memset(data, 1, sizeof(data)); // right memset(data, 0, sizeof(data)); // right 而在初始化其他基础类型时,则需原创 2016-04-05 18:13:39 · 7627 阅读 · 2 评论 -
理解std::move是如何工作的
关于右值引用:(1)右值引用通过&&来获得右值引用,一个重要的性质:只能绑定到一个将要被销毁的对象上,因此我们可以自由的将一个右值引用的资源“移动”到另一个对象中。(2)不能将一个右值引用直接绑定到一个左值上。(3)左值持久,右值短暂:考察左值和右值表达式列表,两者区别就很明显了:左值有持久的状态,而右值要么是字面常量,要么是在表达式求值过程中创建的原创 2016-04-05 14:00:21 · 9646 阅读 · 0 评论 -
C++虚函数实现&&单继承和多继承下的虚函数布局
下面这张图基本说明了多继承下,vptr和vtble的布局:更多详细解答参考博客:http://blog.chinaunix.net/uid-25132162-id-1564955.html原创 2016-04-05 17:16:07 · 293 阅读 · 0 评论