摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 虚函数是面向对象设计中的一个重要内容。它的出现使得我们只需要相同的接口函数,并可以得到不同的生成结果。但是有些朋友却知其然,不知其所以然,为什 么会出现这样的结果,我们可以用一段代码说明问题。首先,我们先定义两个基本类型,一个是employee,一个是manager,看过前面一片博客的朋 友应该都有点印象:[cpp] view plaincopyclassemployee{public:employee(){}~employee(){}virtualvoidprint()const{pri. 阅读全文
posted @ 2012-01-17 10:00 董雨 阅读(197) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 拷贝构造函数和复制函数是类里面比较重要的两个函数。两者有什么区别呢?其实也很简单,我们可以举个例子,加入有这样一个类的定义:[cpp] view plaincopyclassapple{public:apple(){printf("apple()!\n");}apple(apple&a){printf("copyapple()!\n");}apple&operator=(apple&a){printf("=apple( 阅读全文
posted @ 2012-01-17 09:59 董雨 阅读(209) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 继承是类的一个基本属性,可是在类的继承过程中,函数是怎么初始化?怎么析构的呢?我们不妨看看下面这样的一段代码?[cpp] view plaincopyclassemployee{public:employee(){printf("employee()!\n");}~employee(){printf("~employee()!\n");}};classmanager:publicemployee{public:manager(){printf(&quo 阅读全文
posted @ 2012-01-17 09:59 董雨 阅读(211) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 这里说的函数主要指的是inline函数、static函数。inline函数比较特殊,它既具有宏的性质,同时也能让编译器对它进行函数检查。 static函数同样也比较特殊,它只可以被同文件的函数使用。如果static函数在include文件中,那么这个头文件只要被使用一次,那么这个函 数就要在exec文件中重新出现一次。现在大家可能理解起来有点困难,但是请大家稍微等待一下,下面我们将会用示例进行说明。最后,我们用一个替换的技巧 对函数指针进行修改,让你调用的函数发生修改,这样给大家都函数... 阅读全文
posted @ 2012-01-17 09:58 董雨 阅读(189) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 前面我们讨论基本上都是C语言的内容,还没有真正触及到C++的相关知识。从这篇博客之后,我们将会更多触及类的内容。类的属性很多,今天我们讨论主要就是构造函数、析构函数。 (1)如果没有构造函数、析构函数呢?[cpp] view plaincopyclassapple{public:voidprint()const{return;}}; 虽然这个类没有什么意义,但是如果用sizeof计算一下大小的话,我们发现它还是占了一个字节。那么如果有一个apple的变量呢?为了让apple的变量有意义,.. 阅读全文
posted @ 2012-01-17 09:58 董雨 阅读(229) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 嵌入式汇编是对纯汇编文件的一种有益补充。通常会有下面几种情况使用到汇编:(1)提高代码的工作效率 ,使用到cpu的一些特殊指令,比如说mmx指令;(2)对硬件进行某种特殊的操作,比如说关中断等,这在内核级的代码中是比较常见的。但是我们讲究嵌入 式汇编的一些基本点和大家一起讨论一下,建议大家和我一起做实验,用事实证明一切。 (1)使用嵌入汇编的时候,注意寄存器的保护[cpp] view plaincopyintprocess(){__asm{pushaxpushbxpushcxpopcxp.. 阅读全文
posted @ 2012-01-17 09:57 董雨 阅读(243) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 循环是我们编程中遇到的另外一项重要技术。通过反复的迭代运算,我们可以获取想要的任何结果。当然这种迭代是有基本条件的,或是以时间为条件的,或是以 空间为条件的,或者是某一种外来交互作为条件的。循环的方式有很多种,但是常用的还是:while、for、do-while、goto这几种。很多公司 的项目都不喜欢goto,这其中倒不是说goto不好,主要是goto的随意性太大,一旦用的不好,就会降低代码的可读性,反而影响其他人的工作效率。 (1)do-while为什么先执行,后判断? 老规矩,我们还是 阅读全文
posted @ 2012-01-17 09:56 董雨 阅读(190) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 无论是在判断还是在循环的过程中,通常在遇到合适的条件的时候就会退出相应的模块。跳出模块运行的方式很多,break,continue,return都可以。下面我们就可以分别对他们进行将介绍。 (1)continue只能用于循环,而break循环、判断都可以应用。两者有什么区别呢?[cpp] view plaincopy21:for(intm=10;m<100;m++)00401638movdwordptr[ebp-4],0Ah0040163Fjmpprocess+2Ah(0040164a 阅读全文
posted @ 2012-01-17 09:56 董雨 阅读(193) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 (4)指针和引用 引用是C++和语言的区别之一。其实本质上说两者是一致的。朋友们可以看下面两段代码。 a)指针和指针的函数代码[cpp] view plaincopyvoidadd_point(int*q){(*q)++;}voidadd_ref(int&q){q++;} b)函数的调用代码[cpp] view plaincopy56:intm=10;004012E8movdwordptr[ebp-4],0Ah57:add_point(&m);004012EFleaeax,[ 阅读全文
posted @ 2012-01-17 09:55 董雨 阅读(232) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 在我们平常的编程当中,用于判断的地方很多,但主要有下面三种方式:if-else;switch;?:。其中最后一种方式在本质上和if-else是 一样的。switch和if-else其实也一样,如果我们把switch改成if(...) {} else if(...) {} else {},那么你实现的效果和switch实际差不多,熟悉的朋友都会有这样的体验。或许有的朋友还是不太相信,大家可以自己用写实例比较看一下。 (1) switch中的break重要吗?[cpp] view plainco 阅读全文
posted @ 2012-01-17 09:55 董雨 阅读(170) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 指针是我们在C/C++中经常遇到的一种数据类型。指针用的好,可以提高代码的可读性;但是如果使用不恰当,反而会造成很大的麻烦。指针,也就是指向某一 种数据类型的地址。这种类型很多,它可以是编程语言自带的类型,比如说int、long、short、char、float、double、int;也可 是是指向某一种自定义数据类型,可以使union、struct或者是class;甚至指向的数据类型本身即是指针,比如说int*、char*、 short**;当然指针还可以是指向一片内存,表示具有一定长度的 阅读全文
posted @ 2012-01-17 09:54 董雨 阅读(204) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 说到用汇编的眼光看C++语言,那么怎么阅读汇编代码就成了我们需要解决的一个问题。其实,实话说,汇编其实不难。只是我们需要明白这样几个问题: (1)汇编是什么语言? (2)汇编中的主要内容有哪些? (3)汇编语言是怎么和实际C/C++语言代码一一对应的? (1)汇编是什么语言 其实汇编语言是CPU指令码的一种标记符号。不同的CPU具有不同的指令集,普通PC上的CPU一般来自AMD或者是INTEL,使用的也就是我们今天 所要说的X86指令集。其他类似的CPU还有POWERPC,主要来自电信企业的 阅读全文
posted @ 2012-01-17 09:53 董雨 阅读(247) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 很多朋友,包括我自己在内,对C++语言的很多特性不是很明白。特别是几年前找工作的时候,为了应付来自工作单位的考试,我经常逼着自己的去记住一些复 杂的试题和答案。可是常常时间已过,一切又回到了原点。原来没有弄清楚的问题还是没有弄明白,一切都没有发生改变。直到若干年后,当我在编码过程中不断积 累经验,尝试用汇编代码和内存数据来解释一些现象的时候,才明白有些东西其实并不复杂。也许有的朋友对汇编语言会有畏惧,其实没有必要。只要你对C语言有 一些基础,对堆栈有一些印象,那么你已经拥有汇编语言的基础.. 阅读全文
posted @ 2012-01-17 09:52 董雨 阅读(204) 评论(0) 推荐(0)
摘要: http://blog.csdn.net/feixiaoxing/article/details/6998116【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 早在八月份的时候,就陆陆续续写了二十多篇用汇编语言看C++的博客内容。在此为了做一个概括,也为了朋友们看起来更方便,我们利用这么一篇博客对所有的文章做一个总结。如果有朋友们在观看的过程当中发现了问题,恳请多多指教,谢谢。 01)用汇编的眼光看C++(开篇) 02)用汇编的眼光看C++(之X86汇编) 03)用汇编的眼光看C++(之指针1,2) 04)用汇编的眼光看C++(之判断流程 阅读全文
posted @ 2012-01-17 09:51 董雨 阅读(185) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 多线程编程是现代软件技术中很重要的一个环节。要弄懂多线程,这就要牵涉到多进程?当然,要了解到多进程,就要涉及到操作系统。不过大家也不要紧张,听我慢慢道来。这其中的环节其实并不复杂。 (1)单CPU下的多线程 在没有出现多核CPU之前,我们的计算资源是唯一的。如果系统中有多个任务要处理的话,那么就需要按照某种规则依次调度这些任务进行处理。什么规则呢?可以是一些简单的调度方法,比如说 1)按照优先级调度 2)按照FIFO调度 3)按照时间片调度等等 当然,除了CPU资源之外,系统中还有一些其.. 阅读全文
posted @ 2012-01-17 09:49 董雨 阅读(207) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 多线程创建其实十分简单,在windows系统下面有很多函数可以创建多线程,比如说_beginthread。我们就可以利用它为我们编写一段简单的多线程代码,[cpp] view plaincopy#include<windows.h>#include<process.h>#include<stdio.h>unsignedintvalue=0;voidprint(void*argv){while(1){printf("&value=%x,va 阅读全文
posted @ 2012-01-17 09:48 董雨 阅读(163) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 相信有过多线程编程经验的朋友,都吃过死锁的苦。除非你不使用多线程,否则死锁的可能性会一直存在。为什么会出现死锁呢?我想原因主要有下面几个方面: (1)个人使用锁的经验差异 (2)模块使用锁的差异 (3)版本之间的差异 (4)分支之间的差异 (5)修改代码和重构代码带来的差异 不管什么原因,死锁的危机都是存在的。那么,通常出现的死锁都有哪些呢?我们可以一个一个看过来, (1)忘记释放锁[cpp] view plaincopyvoiddata_process(){EnterCr... 阅读全文
posted @ 2012-01-17 09:48 董雨 阅读(230) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 在多线程存在的环境中,除了堆栈中的临时数据之外,所有的数据都是共享的。如果我们需要线程之间正确地运行,那么务必需要保证公共数据的执行和计算是正确 的。简单一点说,就是保证数据在执行的时候必须是互斥的。否则,如果两个或者多个线程在同一时刻对数据进行了操作,那么后果是不可想象的。 也许有的朋友会说,不光数据需要保护,代码也需要保护。提出这个观点的朋友只看到了数据访问互斥的表象。在程序的运行空间里面,什么最重要的呢?代码吗?当然不是。代码只是为了数据的访问存在的。数据才是我们一切工作的出发点和落脚 阅读全文
posted @ 2012-01-17 09:47 董雨 阅读(235) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 在windows系统中,系统本身为我们提供了很多锁。通过这些锁的使用,一方面可以加强我们对锁的认识,另外一方面可以提高代码的性能和健壮性。常用的锁以下四种:临界区,互斥量,信号量,event。 (1)临界区 临界区是最简单的一种锁。基本的临界区操作有,[cpp] view plaincopyInitializeCriticalSectionEnterCriticalSectionLeaveCriticalSectionDeleteCriticalSection 如果想要对数据进行互斥... 阅读全文
posted @ 2012-01-17 09:46 董雨 阅读(202) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 自旋锁是SMP中经常使用到的一个锁。所谓的smp,就是对称多处理器的意思。在工业用的pcb板上面,特别是服务器上面,一个pcb板有多个cpu是 很正常的事情。这些cpu相互之间是独立运行的,每一个cpu均有自己的调度队列。然而,这些cpu在内存空间上是共享的。举个例子说,假设有一个数据 value = 10,那么这个数据可以被所有的cpu访问。这就是共享内存的本质意义。 我们可以看一段Linux 下的的自旋锁代码(kernel 2.6.23,asm-i386/spinlock.h),就可.. 阅读全文
posted @ 2012-01-17 09:46 董雨 阅读(233) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 编写程序不容易,编写多线程的程序更不容易。相信编写过多线程的程序都应该有这样的一个痛苦过程,什么样的情况呢?朋友们应该看一下代码就明白了,[cpp] view plaincopyvoiddata_process(){EnterCriticalSection();if(/*errorhappens*/){LeaveCriticalSection();return;}if(/*othererrorhappens*/){return;}LeaveCriticalSection();} 上面的代码说 阅读全文
posted @ 2012-01-17 09:45 董雨 阅读(274) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 嵌套锁这个概念,主要是为了根据编程中的一种情形引申出来的。什么情况呢,我们可以具体说明一下。假设你在处理一个公共函数的时候,因为中间涉及公共数 据,所以你加了一个锁。但是,有一点比较悲哀。这个公共函数自身也加了一个锁,而且和你加的锁是一样的。所以,除非你的使用的是信号量,要不然你的程序一 辈子也获取不了这个锁。[cpp] view plaincopyHANDLEhLock;voidsub_func(){/*...*/WaitForSingleObject(hLock,INFINITE);d. 阅读全文
posted @ 2012-01-17 09:43 董雨 阅读(332) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 在编写多线程的时候,有一种情况是十分常见的。那就是,有些公共数据修改的机会比较少。相比较改写,它们读的机会反而高的多。通常而言,在读的过程中, 往往伴随着查找的操作,中间耗时很长。给这种代码段加锁,会极大地降低我们程序的效率。那么有没有一种方法,可以专门处理这种多读少写的情况呢? 有,那就是读写锁。 (1)首先,我们定义一下基本的数据结构。[cpp] view plaincopytypedefstruct_RWLock{intcount;intstate;HANDLEhRead;HA... 阅读全文
posted @ 2012-01-17 09:43 董雨 阅读(194) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 生产者-消费者是很有意思的一种算法。它的存在主要是两个目的,第一就是满足生产者对资源的不断创造;第二就是满足消费者对资源的不断索取。当然,因为空间是有限的,所以资源既不能无限存储,也不能无限索取。 生产者的算法,[cpp] view plaincopyWaitForSingleObject(hEmpty,INFINITE);WaitForSingleObject(hMutex,INIFINITE);/*producenewresources*/ReleaseMutex(hMutex);... 阅读全文
posted @ 2012-01-17 09:42 董雨 阅读(207) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 预防死锁的注意事项:(1)在编写多线程程序之前,首先编写正确的程序,然后再移植到多线程(2)时刻检查自己写的程序有没有在跳出时忘记释放锁(3)如果自己的模块可能重复使用一个锁,建议使用嵌套锁(4)对于某些锁代码,不要临时重新编写,建议使用库里面的锁,或者自己曾经编写的锁(5)如果某项业务需要获取多个锁,必须保证锁的按某种顺序获取,否则必定死锁(6)编写简单的测试用例,验证有没有死锁(7)编写验证死锁的程序,从源头避免死锁 首先,定义基本的数据结构和宏,[cpp] view plaincopy 阅读全文
posted @ 2012-01-17 09:41 董雨 阅读(241) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 对于编写多线程的朋友来说,队列具有天生的互斥性。在队列里面,一个负责添加数据,一个负责处理数据。谁也不妨碍谁,谁也离不开谁。所以,队列具有天生的并行性。[cpp] view plaincopy#defineMAX_NUMBER1000L#defineSTATUSint#defineOK0#defineFALSE-1typedefstruct_QUEUE_DATA{intdata[MAX_NUMBER];inthead;inttail;}QUEUE_DATA; 此时,一个线程压入数据,操作为p 阅读全文
posted @ 2012-01-17 09:40 董雨 阅读(280) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 软件调试是我们软件开发过程中的重要一课。在前面,我们也讨论过程序调试,比如说这里。今天,我们还可以就软件调试多讲一些内容。比如说条件断点,数据断点,多线程断点等等。[cpp] view plaincopy#include<stdio.h>intvalue=0;voidtest(){inttotal;intindex;total=0;for(index=0;index<100;index++)total+=index*index;value=total;return;}int 阅读全文
posted @ 2012-01-17 09:40 董雨 阅读(208) 评论(0) 推荐(0)
摘要: 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 在互斥数据访问中有一种多读少写的情况。正对这么一种情形,我们也提出了读写锁的方案。但是呢,这个锁有些缺陷。什么缺陷呢?那就是,这个写锁需要在所有的读锁完成之后才能写。否则的话,写锁需要这么一直等下去。 那么,有没有什么办法能使得写操作快速一点进行呢?那就是顺序锁。[cpp] view plaincopytypedefstruct_SEQUENCE_LOCK{unsignedintsequence;HANDLEhLock;}SEQUENCE_LOCK; 有了这么一个数据结构之后。那么读锁怎么. 阅读全文
posted @ 2012-01-17 09:39 董雨 阅读(229) 评论(0) 推荐(0)
摘要: http://blog.csdn.net/feixiaoxing/article/details/7055128【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 前面,为了使得写操作快速进行,我们定义了顺序锁。但是顺序锁有个缺点,那就是处理的数据不能是指针,否则可能会导致exception。那么有没有办法使得处理的数据包括指针呢?当然要是这个链表没有锁,那就更好了。 针对这种无锁链表,我们可以初步分析一下,应该怎么设计呢? (1)读操作没有锁,那么怎么判断读操作正在进行呢,只能靠标志位了; (2)写操作没有锁,那么读操作只能一个线... 阅读全文
posted @ 2012-01-17 09:37 董雨 阅读(500) 评论(0) 推荐(0)
摘要: http://blog.csdn.net/feixiaoxing/article/details/7058393【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 要想编写多线程,那就要使用锁。而在软件编写中,数据结构是少不了的。所以,我们在编写多线程的时候,就需要考虑一下如何在数据结构中插入锁。当然,有些数据结构是没有锁的,所以自然这个锁并不一定是必须的。 比如说,我们编写一个多线程堆栈,应该怎么做呢,[cpp] view plaincopytypedefstruct_STACK{void*pData;intmaxLen;inttop... 阅读全文
posted @ 2012-01-17 09:36 董雨 阅读(261) 评论(0) 推荐(0)