随笔分类 -  C++

1
摘要:转自:http://www.builder.com.cn/2008/0104/696370.shtml“new”是C++的一个关键字,同时也是操作符。关于new的话题非常多,因为它确实比较复杂,也非常神秘,下面我将把我了解到的与new有关的内容做一个总结。new的过程当我们使用关键字new在堆上动态创建一个对象时,它实际上做了三件事:获得一块内存空间、调用构造函数、返回正确的指针。当然,如果我们创建的是简单类型的变量,那么第二步会被省略。假如我们定义了如下一个类A:class A{ int i;public: A(int _i) :i(_i*_i) {} void Say() { printf 阅读全文
posted @ 2011-04-10 17:13 andriod2012 阅读(117) 评论(0) 推荐(0) 编辑
摘要:堆和栈的区别一、预备知识—程序的内存分配一个由c/C++编译的程序占用的内存分为以下几个部分1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。2、堆区(heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。-程序结束后有系统释放4、文字常量区—常量字符串就是放在这里的。程序结束后 阅读全文
posted @ 2011-04-10 16:37 andriod2012 阅读(150) 评论(0) 推荐(0) 编辑
摘要:以前写代码,很少使用union,所以在潜意识中,经常将其忽略。最近要写个生成一段数据的程序,数据类型有两种,一种保护的数据多些,另一种只包含第一种中的部分数据。因为潜意识中没有union,所以开始也没想到用union来实现。给同事讨论时,同事提示用union时,自己才想起来,C++中还有union。 依次为契机,就在网上查了些介绍union的资料,给自己补补课。下面总结了一下使用union的几个注意点,深层次的东西就不去探讨了。1、共享内存 也就是共享起始地址。union变量中,可以包含union中的任何一个成员,但是该union变量的起始地址是固定的。2、取最大成员的空间 既然union变. 阅读全文
posted @ 2010-08-25 13:54 andriod2012 阅读(445) 评论(0) 推荐(0) 编辑
摘要:今天一同事在用fwrite向文件中写数据时,当写入0x0A时,其前面总会被加上一个0x0D。后来在网上查了,发现也有人遇到类似问题。出现这个问题的原因是fwrite 在以文本方式写文件时,碰到0x0A,会自动在前面加上0x0D,以够成回车换行符。解决办法是以二进制方式打开文件,然后进行写文件。出问题的代码:fopen( filename, "w+" );解决问题的代码:fopen( filename, "wb+" ); 阅读全文
posted @ 2010-08-18 17:11 andriod2012 阅读(903) 评论(0) 推荐(0) 编辑
摘要:简单介绍一下这几个关键字,以前也看过多次,基本上是看过了就忘,忘了再看。这次又看了下,把自己的理解说下。先说说 const,这儿只说const修饰变量的情况。const用于定义一个常量,也就是说定义的这个变量其实是不可变的。但是不可变只是对于当前代码段来说的,并不是说这个变量绝对的不可变。例如,系统中断如果要修改这个变量的值的话,const就无法阻止了。volitale是用来告诉编译器,某个变量,不仅在当前代码段中可能被修改,也可能被其他程序修改,如中断等。所以,就算当前代码中没有修改该变量的值,但它的值也可能被其他地方修改而改变。一般编译器都会做一些优化操作,如下:int i = 10;in 阅读全文
posted @ 2010-08-13 12:32 andriod2012 阅读(215) 评论(1) 推荐(0) 编辑
摘要:函数malloc()和calloc()都可以用来动态分配内存空间,但两者稍有区别。malloc()函数有一个参数,即要分配的内存空间的大小:void*malloc(size_tsize);calloc()函数有两个参数,分别为元素的数目和每个元素的大小,这两个参数的乘积就是要分配的内存空间的大小。void*calloc(size_tnumElements,size_tsizeOfElement);如果调用成功,函数malloc()和函数calloc()都将返回所分配的内存空间的首地址。函数malloc()和函数calloc() 的主要区别是前者不能初始化所分配的内存空间,而后者能。如果由mal 阅读全文
posted @ 2010-06-19 21:47 andriod2012 阅读(134) 评论(0) 推荐(0) 编辑
摘要:• ExceptionFlags包含有关异常的标志。当前只有两个值,分别是0(指出一个可以继续的异常)和E X C E P T I O N _ N O N C O N T I N U A B L E(指出一个不可继续的异常)。在一个不可继续的异常之后,若要继续执行,会引发一个E X C E P T I O N _ N O N C O N T I N U A B L E _E X C E P T I O N异常。• E x c e p t i o n R e c o r d指向另一个未处理异常的E X C E P T I O N _ R E C O R D结构。在处理一个异常的时候,有可能引发另 阅读全文
posted @ 2009-03-27 15:21 andriod2012 阅读(117) 评论(0) 推荐(0) 编辑
摘要:有可能发生在一个f i n a l l y块、一个异常过滤器、或一个异常处理程序里。当发生这种情况时,系统压栈异常。回忆一下G e t E x c e p t i o n I n f o r m a t i o n函数。这个函数返回EXCEPTION_ POINTERS结构的地址。E X C E P T I O N _ P O I N T E R S的E x c e p t i o n R e c o r d成员指向一个EXCEPTION_ R E C O R D结构,这个结构包含另一个E x c e p t i o n R e c o r d成员。这个成员是一个指向另外的E X C E P 阅读全文
posted @ 2009-03-27 15:21 andriod2012 阅读(134) 评论(0) 推荐(0) 编辑
摘要:下面的代码举例说明了一种方法,指出所发生异常的类别:BOOL Func_SEHExceptionGetCodeBase(){int x,y;__try{x = 0;y = 4/x;}__except((GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO) ? / EXCEPTION_EXECUTE_HANDLER :/ EXCEPTION_CONTINUE_SEARCH){file://handle divide by zero exception}}GetExceptionCode返回一个值,该值指出所发生异常的种类:下面列出所有预定义的异常 阅读全文
posted @ 2009-03-27 15:19 andriod2012 阅读(154) 评论(0) 推荐(0) 编辑
摘要:在现在,软件变的越来越大,如果不用SEH,要实现完全强壮的应用程序简直是不可能的。我们先来看一个样板程序,即C的运行时函数strcpy:这是一个相当简单的函数,它怎么会引起一个进程结束呢?如果调用者对这些参数中的某一个传递NULL(或任何无效的地址),strcpy就引起一个存取异常,并且导致整个进程结束。使用SEH,就可以建立一个完全强壮的strcpy函数:char* RobustStrcpy(char* strDes, char* strSource){__try{strcpy(strDes, strSource);}__except(EXCEPTION_EXECUTE_HANDLER){f 阅读全文
posted @ 2009-03-27 15:18 andriod2012 阅读(149) 评论(0) 推荐(0) 编辑
摘要:*lpAddress = ''''A''''; // <- Here, Will Happen a Access Exception! VirtualFree((LPVOID)lpAddress, 1024, MEM_RELEASE); return dwReturnValue;}DWORD Func_SEHTerminate(){DWORD dwReturnData = 0; HANDLE hSem = NULL;const char* lpSemName = "TermSem";hSem = Crea 阅读全文
posted @ 2009-03-27 15:17 andriod2012 阅读(126) 评论(0) 推荐(0) 编辑
摘要:finally块的总结性说明我们已经明确区分了强制执行f i n a l l y块的两种情况:• 从t r y块进入f i n a l l y块的正常控制流。• 局部展开:从t r y块的过早退出(g o t o、l o n g j u m p、c o n t i n u e、b r e a k、r e t u r n等)强制控制转移到f i n a l l y块。第三种情况,全局展开( global unwind),在发生的时候没有明显的标识,我们在本章前面Func_SEHTerminate函数中已经见到。在Func_SEHTerminate的t r y块中,有一个对TermHappenSo 阅读全文
posted @ 2009-03-27 15:17 andriod2012 阅读(138) 评论(0) 推荐(0) 编辑
摘要:微软在Wi n d o w s中引入S E H的主要动机是为了便于操作系统本身的开发。操作系统的开发人员使用S E H,使得系统更加强壮。我们也可以使用S E H,使我们的自己的程序更加强壮。使用S E H所造成的负担主要由编译程序来承担,而不是由操作系统承担。当异常块(exception block)出现时,编译程序要生成特殊的代码。编译程序必须产生一些表( t a b l e)来支持处理S E H的数据结构。编译程序还必须提供回调( c a l l b a c k)函数,操作系统可以调用这些函数,保证异常块被处理。编译程序还要负责准备栈结构和其他内部信息,供操作系统使用和参考。在编译程序中 阅读全文
posted @ 2009-03-27 15:16 andriod2012 阅读(141) 评论(0) 推荐(0) 编辑
摘要:file://异常}catch (logic_error& ex) { // 处理所有其它的 ... // logic_errors异常}综上所述,把一个对象传递给函数或一个对象调用虚拟函数与把一个对象做为异常抛出,这之间有三个主要区别。第一、异常对象在传递时总被进行拷贝;当通过传值方式捕获时,异常对象被拷贝了两次。对象做为参数传递给函数时不需要被拷贝。第二、对象做为异常被抛出与做为参数传递给函数相比,前者类型转换比后者要少(前者只有两种转换形式)。最后一点,catch子句进行异常类型匹配的顺序是它们在源代码中出现的顺序,第一个类型匹配成功的catch将被用来执行。当一个对象调用一个虚 阅读全文
posted @ 2009-03-27 15:15 andriod2012 阅读(171) 评论(0) 推荐(0) 编辑
摘要:对象从函数的调用处传递到函数参数里与从异常抛出点传递到catch子句里所采用的方法不同,这只是参数传递与异常传递的区别的一个方面,第二个差异是在函数调用者或抛出异常者与被调用者或异常捕获者之间的类型匹配的过程不同。比如在标准数学库(the standard math library)中sqrt函数:double sqrt(double); // from <cmath> or <math.h>我们能这样计算一个整数的平方根,如下所示:int i;double sqrtOfi = sqrt(i);毫无疑问,C++允许进行从int到double的隐式类型转换,所以在sqrt 阅读全文
posted @ 2009-03-27 15:14 andriod2012 阅读(134) 评论(0) 推荐(0) 编辑
摘要:当异常对象被拷贝时,拷贝操作是由对象的拷贝构造函数完成的。该拷贝构造函数是对象的静态类型(static type)所对应类的拷贝构造函数,而不是对象的动态类型(dynamic type)对应类的拷贝构造函数。比如以下这经过少许修改的passAndThrowWidget:class Widget { ... };class SpecialWidget: public Widget { ... };void passAndThrowWidget(){ SpecialWidget localSpecialWidget; ... Widget& rw = localSpecialWidget; 阅读全文
posted @ 2009-03-27 15:12 andriod2012 阅读(156) 评论(0) 推荐(0) 编辑
摘要:}很多window系统有C-like接口,使用象like createWindow 和 destroyWindow函数来获取和释放window资源。如果在w对应的window中显示信息时,一个异常被抛出,w所对应的window将被丢失,就象其它动态分配的资源一样。解决方法与前面所述的一样,建立一个类,让它的构造函数与析构函数来获取和释放资源:file://一个类,获取和释放一个window 句柄class WindowHandle {public: WindowHandle(WINDOW_HANDLE handle): w(handle) {} ~WindowHandle() { destr. 阅读全文
posted @ 2009-03-27 15:11 andriod2012 阅读(134) 评论(0) 推荐(0) 编辑
摘要:bad_typeid 报告在表达式typeid(*p)中有一个空指针P④ 由runtime_error派生的异常range_error 报告违反了后置条件overflow_error 报告一个算术溢出bad_alloc 报告一个存储分配错误使用析构函数防止资源泄漏这部分是一个经典和很平常就会遇到的实际情况,下面的内容大部分都是从More Effective C++条款中得到的。假设,你正在为一个小动物收容所编写软件,小动物收容所是一个帮助小狗小猫寻找主人的组织。每天收容所建立一个文件,包含当天它所管理的收容动物的资料信息,你的工作是写一个程序读出这些文件然后对每个收容动物进行适当的处理(app 阅读全文
posted @ 2009-03-27 15:10 andriod2012 阅读(148) 评论(0) 推荐(0) 编辑
摘要:}} void main(){ ExceptionClass e("Test"); try{ e.mythrow(); } catch(...) { cout<<”*********”<<endl; }}这是输出信息:Construct TestConstruct my throwDestruct my throw****************Destruct my throw (这里是异常处理空间中对异常类的拷贝的析构)Destruct Test======================================不过一般来说我们可能更习惯 阅读全文
posted @ 2009-03-27 15:08 andriod2012 阅读(123) 评论(0) 推荐(0) 编辑
摘要:这两天要处理一个异常的问题,刚好查了些相关的资料。在网上看到了一个不错的贴子,就转了过来,方便本人,以及来此旅游的朋友学习。源地址:http://www.host01.com/Print.html?91983,1异常处理的基本思想是简化程序的错误代码,为程序键壮性提供一个标准检测机制。也许我们已经使用过异常,但是你会是一种习惯吗,不要老是想着当我打开一个文件的时候才用异常判断一下,我知道对你来说你喜欢用return value或者是print error message来做,你想过这样做会导致Memory Leak,系统退出,代码重复/难读,垃圾一堆…..吗?现在的软件已经是n*365*24小 阅读全文
posted @ 2009-03-27 15:04 andriod2012 阅读(135) 评论(0) 推荐(0) 编辑

1
点击右上角即可分享
微信分享提示