??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
Java~程语言Q第三版)---Java四大名著----James Gosling(Java之父)
Java~程思想Q第2?----Java四大名著----Bruce Eckel
Java~程思想Q第3?----Java四大名著----------------Bruce Eckel
JAVA 2核心技?卷IQ基知识Q原书第7版)---Java四大名著-----Cay Horstmann
JAVA 2核心技?卷IIQ高U特性(原书W??----Java四大名著-----Cay Horstmann
Effective Java中文?-----Java四大名著--------Joshua Bloch
_NStruts:ZMVC的Java Web设计与开?--孙卫?
_NHibernateQJava对象持久化技术详?--孙卫?
Tomcat与Java Web开发技术详?-----------孙卫?
Java与模?-----------------------------阎宏
2、c#
C#E序设计-------Charles Petzold“windows~程泰山北斗”---C#语言“倚天屠龙双剑”
C# Primer中文?-------Stanley B.Lippman---C#语言“倚天屠龙双剑”
.NET框架E序设计Q修订版)--------Jeffrey Richter“windows~程泰山北斗”---.NETq_四大天王
c#WindowsE序设计----------Charles Petzold“windows~程泰山北斗”------.NETq_四大天王
.NETE序设计技术内q?------------Jeff Prosise---.NETq_四大天王
.NET本质?-W?P公共语言q行?中文?--------Chris Sells---.NETq_四大天王
3、C++
C++E序设计语言Q特别版)---c++八大金刚----Bjarne Stroustrup“C++之父”
C++ Primer (W??中文?---c++八大金刚---Stanley B.Lippman
C++ Primer (W??中文?---c++八大金刚---Stanley B.Lippman
C++标准E序库—自修教E与参考手?-c++八大金刚--Nicolai M.Josuttis
C++语言的设计和演化-----c++八大金刚----Bjarne Stroustrup“C++之父”
深度探烦C++对象模型---c++八大金刚----Stanley B.Lippman
Essential C++中文?--c++八大金刚---Stanley B.Lippman
Effective C++中文?2nd Edition-----c++八大金刚------Scott Meyers
More Effective C++中文?---c++八大金刚------Scott Meyers
C++~程思想Q第2版) W?P标准C++导引--------Bruce Eckel
C++~程思想Q第2版)W?P实用~程技?--------Bruce Eckel
C++E序设计--------------------------谭浩?
C++ E序设计教程(W??--------------p
C++ Primer Plus(W五?中文?--Stephen Prata
q博如四库全书The c++ programming language、c++ Primer
深奥如山重水复Inside the c++ object model
E序库大全The c++ standard libray
工程l验之积累Effective c++、More Effective c++、Exceptional c++
c++八大金刚Q?
1、Essentital c++---lippman---C++之父Q旁枝暂略,L核心Q轻薄短,初学?
2、The c++ programming language----C++之父Q技术权威,用词深峻Q思想pQc++癄全书代表
3、c++ Primer----lippman---U|书市十数q_c++最x本,c++癄全书代表?
4、Inside the c++ object model-----lippman----揭示c++底层Q非常好Q非帔R?
5、Effective c++-----通过50个编E实例,展示专家l验Q行文有,深处出?
6、More Effective c++Q-Q-通过35个编E实例,展示专家l验Q行文有,深处出?
7、The c++ standard librayQ-Qc++标准库的癄全书?
8、设计模式:可复用面向对象Y件的基础
4、c
CE序设计语言Q第2?#183;新版Q?--C语言“倚天屠龙双剑”---Brian W.Kernighan“C语言之父”
C Primer Plus中文版(W五版)--------C语言“倚天屠龙双剑”---Stephen Prata
CE序设计Q第三版Q?--------------------------谭浩?
C语言大全Q第四版Q?--------------------------HERBERT SCHILDT
C语言接口与实玎ͼ创徏可重用Y件的技?------------DAVID R.HANSON
C语言参考手?原书W??--------------------------Samuel P.Harbison
CE序设计教程---------------------------------H.M.Deitel/P.J.Deitel
C陷阱与缺?----------------------------------Andrew Koenig
5、VB
Visual Basic .NET技术内q?----VB~程三剑?----------Francesco Balena“vb首席大师”
WindowsE序设计-Visual Basic.NET语言描述--VB~程三剑?----Charles Petzold“windows~程泰山
北斗”---
.NET框架E序设计QVisual Basic.NET语言描述--VB~程三剑?-Jeffrey Richter“windows~程泰山?
?#8221;---QFrancesco Balena“vb首席大师”
Visual Basic 6~程技术大?-----------------------Francesco Balena“vb首席大师”
Visual Basic.NET 从入门到_N?------------------------Petroutsos,E.
高VISUAL BASIC~程-----------------------------------MATTHEW CURLAND
6、Delphi
Inside VCL(深入核心——VCL架构剖析)----------李维
Delphi 7高效数据库程序设?-------------李维
面向对象开发实践之路(Delphi版)----------李维
7、VC
Windows E序设计Q第5版)-----Charles Petzold“windows~程泰山北斗”---
Windows核心~程----------Jeffrey Richter“windows~程泰山北斗”---
Windows高~程指南---------Jeffrey Richter“windows~程泰山北斗”---
深入出MFCQ第二版Q?----“MFC四大天王”-------侯捷
MFC WindowsE序设计Q第2?---MFC四大天王”---------Jeff Prosise
Visual C++ 技术内q(W??--MFC四大天王”--------David Kruglinski
深入解析MFC-------------MFC四大天王”-----------George Shepherd
Visual C++.NET 技术内q(W??-MFC四大天王”------------David Kruglinski
8、vf
Visual FoxproE序设计参考手?------------------张洪?
专家门诊——Visual FoxPro开发答?60?------------------张洪?
Visual FoxPro 6.0/9.0解决Ҏ与范例大?------------------张洪?
Visual FoxPro软g开发模式与应用案例-------------------张洪?
9、黑?
应用密码?协议法与C源程?----------Bruce Schneier
|络信息安全的真?----------Bruce Schneier
黑客大曝光:|络安全机密与解x案(W?版)--------STUART MCCLURE
软g加密技术内q?-----------看雪学院
加密与解密——Y件保护技术与完全解决Ҏ------------看雪学院
加密与解密(W二版)--------D钢
10、汇~?
Intel微处理器l构、编E与接口Q第六版Q?--------Barry B. Brey
80*86、奔腾机汇编语言E序设计---------Barry B. Brey
Windows环境?2位汇~语aE序设计Q第2?-----------|云?
IBM-PC汇编语言E序设计Q第2版) 本书是国内优U教材--------沈美?温冬?
IBM PC汇编语言E序设计Q第五版Q?q本书籍是国外优U教材-------PETER ABEL?沈美?温冬蝉译
11、驱动开?
Windows WDM讑֤驱动E序开发指?----------------------------------- Chris Cant
Windows 2000/XP WDM讑֤驱动E序开?W??--------------------------武安?
WINDOWS 2000/XP WDM讑֤驱动E序开?------------------------------- 武安?
12、网l?
计算机网l第四版中文?---|络~程三剑?-------------Andrew S.Tanenbaum
TCP/IP详解3h--------------------Richard Stevens----|络~程三剑?
UNIX|络~程2h--------------------Richard Stevens----|络~程三剑?
用TCP/IPq行|际互联-----------Douglas E. Comer
高TCP/IP~程-------------------Jon C. Snader
C++|络~程-----------------------Douglas Schmidt
UNIX环境高~程Q第2?--------------------Richard Stevens
13、算?
计算机程序设计艺?------Donald.E.Knuth----------法“倚天屠龙”双剑
法D-----------------Thomas H. Cormen--------法“倚天屠龙”双剑
L数学及其应用----------Kenneth H.Rosen
具体数学—计机U学基础--------Donald.E.Knuth
14、图形编E?
Windows 囑Ş~程----------------FENG YUAN --囑Ş~程界的Charles Petzold之书
15、数据结?
数据l构 C++语言描述?8.00(Data Structures C++) William Ford,William Topp 刘卫?沈官?
数据l构法与应?C++语言描述?9.00Sartej Sahni 汪诗?孙晓东等机械工业出版C?
16、Y件工E?
设计模式--可复用面向对象Y件的基础
重构—改善既有代码的设计
17、操作系l?
深入理解计算机系l(修订版)-------RANDAL E.BRYANT
18、Unix
UNIX |络~程 卷I 套接字联|APIQ英文版 W三?
UNIX ~程艺术
UNIX环境高~程Q英文媄印第2?----UNIX~程“圣经
UNIX环境高~程Q英文媄印版Q(W?版)
99-UNIX环境高~程Q第2版)
UNIX环境高~程Q第2?---UNIX~程“圣经
UNIX|络~程 W?P套接口APIQ第3版)
UNIX|络~程?Q进E间通信Q第2版)Q英文媄印版Q?
UNIX |络~程Q第二版Q第2Pq程间通信
UNIX~程环境
UNIX |络~程 卷I 套接字联|APIQ英文版 W三?
UNIXpȝ~程
UNIX环境高~程
UNIX环境高~程Q英文媄印版
88-LINUX内核分析及编E?
UNIX |络~程 卷I 套接字联|APIQ英文版 W三版)
UNIX|络~程 W?P套接口APIQ第3版)
UNIX |络~程Q第二版Q第2Pq程间通信
UNIX|络~程?Q进E间通信Q第2版)Q英文媄印版Q?
UNIX |络~程Q第2版)W?P套接口API和X/Open 传输接口API
UNIX|络~程Q卷1Q:q网的APLSQ套接字与XTIQ第二版)Q英文媄印版Q?
UNIX环境高~程
UNIX 环境高~程Q英文版Q?
UNIX环境高~程Q第2版)
Unix技术手?
19、Linux
Linux内核设计与实?
Linux内核完全注释
LINUX内核分析及编E?
GNU/Linux ~程指南Q第二版Q?
Linux讑֤驱动E序Q第三版Q?
嵌入式设计及Linux驱动开发指南——基于ARM 9处理?
Linux讑֤驱动E序 W三版(英文影印版)
Linux内核设计与实玎ͼW?版)
Linux内核设计与实玎ͼ英文影印版)Q第2版)
linux技术手?
20、游戏编E?
Windows游戏~程大师技巧(W二?
游戏之旅--我的~程感悟
OpenGL宝典Q第三版
OpenGL~程指南Q第四版Q?
Java 游戏高~程
J2ME手机游戏~程入门
游戏之旅——我的编E感?
游戏开发中的h工智能(英文影印版)
3D游戏Q卷2 动画与高U实时渲染技?
面向对象的游戏开?
Java 游戏高~程
3D游戏~程大师技?
游戏~程_a
面向对象的游戏开?
3D游戏 ?Q实时渲染与软g技?
3D游戏Q卷2 动画与高U实时渲染技…
J2ME手机游戏~程入门
Direct3D游戏~程入门教程Q第二版…
21、移动开?
Windows Mobile手机应用开?
SYMBIAN OS C++手机应用开?
68-Windows Mobile手机应用开?-傅曦 齐宇 徐骏
48-SYMBIAN OS C++手机应用开?Q第2P------------------RICHARD HARRISON?周良?王伯ƣ译
68-SYMBIAN OS C++手机应用开?--------------RICHARD HARRISON?周良忠译
Windows CE.net内核定制及应用程序开?--------周毓?宁杨 陆贵?付林?
嵌入式系lWindows CE 开发技巧与实例--傅曦
Palm OS~程实践---l版
22、单片机
单片村օ?---------------------------------周坚(q_老师)
单片机典型模块设计实例导?----------------------求是U技
例说8051----------------------------------------张义?陈敌?
KEIL CX51 V7.0单片机高U语a~程?#924;VISION2应用实践-----徐爱?nbsp;
单片机应用程序设计技?修订?--------------------周航?
8051单片机实践与应用-------------------------------吴金?
MCS-51pd单片机实用接口技?--------------------李华
23、串q口通讯
Visual C++/Turbo C串口通信~程实践------------------龚徏?
VISUAL BASIC与RS-232串行通信控制Q最新版Q?---------范怹
24、电?
无线电识图与电\故障分析L入门(W二? -------------------胡斌
无线电元器g与修理技术轻村օ门(W二版) -------------------胡斌
图表l说电子技术识?------------------胡斌
图表l说电子元器?------------------胡斌
图表l说元器件及实用电\-------------------胡斌
在C语言的学习中Q对内存理q部分的知识掌握其重要Q之前对C中的malloc()和free()两个函数的了解甚,只知道大概该怎么用——就是malloc然后free׃切OK了。当然现在对q两个函数的体会也不见得多,不过对于本文章第三部分的内容倒是有了转折性的认识Q所以写下这文章作Z个对知识的ȝ。这文章之所以命名中有个“谈”的字|也就是这个意思了Q希望对大家有一点帮助!
如果不扯得太q的话(比如说操作系l中虚拟内存和物理内存如何运做如何管理之cȝ知识{)Q我感觉q篇文章应该是比较全面地谈了一下malloc()和free().q篇文章由浅入深Q不见得有多深)分三个部分介l主要内宏V?/p>
废话了那么多Q下面立刻进入主?===============》》》》》》》》》》》》》》》》》》》》?/p>
一、malloc()和free()的基本概念以及基本用法:
1、函数原型及说明Q?/p>
void *malloc(long NumBytes)Q该函数分配了NumBytes个字节,q返回了指向q块内存的指针。如果分配失败,则返回一个空指针QNULLQ?/p>
关于分配p|的原因,应该有多U,比如说空间不_是一U?/p>
void free(void *FirstByte)Q?该函数是之前用malloc分配的空间还l程序或者是操作pȝQ也是释放了这块内存,让它重新得到自由?/p>
2、函数的用法Q?/p>
其实q两个函数用h倒不是很难,也就是malloc()之后觉得用够了就甩了它把它给free()了,举个单例子:
// Code...
char *Ptr = NULL;
Ptr = (char *)malloc(100 * sizeof(char));
if (NULL == Ptr){
exit (1);
}
gets(Ptr);
// code...
free(Ptr);
Ptr = NULL;
// code...
是q样Q当Ӟ具体情况要具体分析以及具体解冟뀂比如说Q你定义了一个指针,在一个函数里甌了一块内存然后通过函数q回传递给q个指针Q那么也讔R放这块内存这工作就应该留给其他函数了?/p>
3、关于函C用需要注意的一些地方:
A、申请了内存I间后,必须查是否分配成功?/p>
B、当不需要再使用甌的内存时Q记得释放;释放后应该把指向q块内存的指针指向NULLQ防止程序后面不心使用了它?/p>
C、这两个函数应该是配寏V如果申请后不释攑ְ是内存泄Ԍ如果无故释放那就是什么也没有做。释攑֏能一ơ,如果释放两次及两ơ以上会出现错误Q释攄指针例外Q释攄指针其实也等于啥也没做,所以释攄指针释放多少ơ都没有问题Q?/p>
D、虽然malloc()函数的类型是(void *),Mcd的指针都可以转换?void *),但是最好还是在前面q行强制cd转换Q因样可以躲q一些编译器的检查?/p>
二、malloc()到底从哪里得来了内存I间Q?/p>
1、malloc()到底从哪里得C内存I间Q答案是从堆里面获得I间。也是说函数返回的指针是指向堆里面的一块内存。操作系l中有一个记录空闲内存地址的链表。当操作pȝ收到E序的申hQ就会遍历该链表Q然后就LW一个空间大于所甌I间的堆l点Q然后就该l点从空闲结炚w表中删除Qƈ该l点的空间分配给E序。就是这P
说到q里Q不得不另外插入一个小话题Q相信大家也知道是什么话题了。什么是堆?说到堆,又忍不住说到了栈Q什么是栈?下面另外开个小部分专门而又单地说一下这个题外话Q?/p>
2、什么是堆:堆是大家共有的空_分全局堆和局部堆。全局堆就是所有没有分配的I间Q局部堆是用户分配的空间。堆在操作系l对q程 初始化的时候分配,q行q程中也可以向系l要额外的堆Q但是记得用完了要还l操作系l,要不然就是内存泄漏?/p>
什么是栈:栈是U程独有的,保存其运行状态和局部自动变量的。栈在线E开始的时候初始化Q每个线E的栈互相独立。每个函数都有自q栈,栈被用来在函C间传递参数。操作系l在切换U程的时候会自动的切换栈Q就是切换SS/ESP寄存器。栈I间不需要在高语言里面昑ּ的分配和释放?
以上的概忉|q是标准的描qͼ不过有个别语句被我删除,不知道因栯变得不标准了^_^.
通过上面Ҏ늚描述Q可以知道:
栈是q译器自动分配释放Q存攑և数的参数倹{局部变量的值等。操作方式类g数据l构中的栈?/p>
堆一般由E序员分配释放,若不释放Q程序结束时可能由OS回收。注意这里说是可能,q一定。所以我惛_一ơ,记得要释放!
注意它与数据l构中的堆是两回事,分配方式倒是cM于链表。(q点我上面稍微提q)
所以,举个例子Q如果你在函C面定义了一个指针变量,然后在这个函数里甌了一块内存让指针指向它。实际上Q这个指针的地址是在栈上Q但是它所指向的内容却是在堆上面的Q这一点要注意Q所以,再想惻I在一个函数里甌了空间后Q比如说下面q个函数Q?/p>
// code...
void Function(void)
{
char *p = (char *)malloc(100 * sizeof(char));
}
p个例子,千万不要认ؓ函数q回Q函数所在的栈被销毁指针也跟着销毁,甌的内存也׃栯着销毁了Q这l对是错误的Q因为申L内存在堆上,而函数所在的栈被销毁跟堆完全没有啥关系。所以,q是那句话:记得释放Q?/p>
3、free()到底释放了什?/p>
q个问题比较单,其实我是惛_W二大部分的题目相呼应而已Q哈哈!free()释放的是指针指向的内存!注意Q释攄是内存,不是指针Q这炚w帔R帔R要!指针是一个变量,只有E序l束时才被销毁。释放了内存I间后,原来指向q块I间的指针还是存在!只不q现在指针指向的内容的垃圾,是未定义的,所以说是垃圾。因此,前面我已l说q了Q释攑ֆ存后把指针指向NULLQ防止指针在后面不小心又被解引用了。非帔R要啊q一点!
好了Q这?#8220;题外?#8221;l于说完了。就q么单说一ơ,知道个大概就可以了!下面p入第三个部分Q?/p>
三、malloc()以及free()的机Ӟ
q个部分我今天才有了新的认识Q而且是{折性的认识Q所以,q部分可能会有更多一些认识上的错误!不对的地方请大家帮忙指出Q?/p>
事实上,仔细看一下free()的函数原型,也许也会发现g很神奇,free()函数非常单,只有一个参敎ͼ只要把指向申L间的指针传递给free()中的参数可以完成释攑ַ作!q里要追t到malloc()的申请问题了。申L时候实际上占用的内存要比申L大。因出的I间是用来记录对q块内存的管理信息。先看一下在《UNIX环境高~程》中W七章的一D话Q?/p>
大多数实现所分配的存储空间比所要求的要E大一些,额外的空间用来记录管理信息——分配块的长度,指向下一个分配块的指针等{。这意味着如果写过一个已分配区的Q则会改写后一块的理信息。这U类型的错误是灾难性的Q但是因U错误不会很快就暴露出来Q所以也很隑֏现。将指向分配块的指针向后Ud也可能会改写本块的管理信息?/p>
以上q段话已l给了我们一些信息了。malloc()甌的空间实际我觉得是分了两个不同性质的空间。一个就是用来记录管理信息的I间Q另外一个就是可用空间了。而用来记录管理信息的实际上是一个结构体。在C语言中,用结构体来记录同一个对象的不同信息是天l地义的事!下面看看q个l构体的原型Q?/p>
struct mem_control_block {
int is_available; //q是一个标讎ͼ
int size; //q是实际I间的大?/p>
};
对于size,q个是实际空间大。这里其实我有个疑问Qis_available是否是一个标讎ͼ因ؓ我看了free()的源代码之后对这个变量感觉有点纳P源代码在下面分析Q。这里还请大家指出!
所以,free()是Ҏq个l构体的信息来释放malloc()甌的空_而结构体的两个成员的大小我想应该是操作系l的事了。但是这里有一个问题,malloc()甌I间后返回一个指针应该是指向W二U空_也就是可用空_不然Q如果指向管理信息空间的话,写入的内容和l构体的cd有可能不一_或者会把管理信息屏蔽掉Q那没法释攑ֆ存空间了Q所以会发生错误Q(感觉自己q里说的是废话)
好了Q下面看看free()的源代码Q我自己分析了一下,觉得比vmalloc()的源代码倒是Ҏ单很多。只是有个疑问,下面指出Q?/p>
// code...
void free(void *ptr)
{
struct mem_control_block *free;
free = ptr - sizeof(struct mem_control_block);
free->is_available = 1;
return;
}
看一下函数第二句Q这句非帔R要和关键。其实这句就是把指向可用I间的指针倒回去,让它指向理信息的那块空_因ؓq里是在g减去了一个结构体的大!后面那一句free->is_available = 1;我有点纳P我的x是:q里is_available应该只是一个标记而已Q因Zq个变量的名UC来看Qis_available 译q来是“是可以用”。不要说我土Q我觉得变量名字可以反映一个变量的作用Q特别是严}的代码。这是源代码Q所以我觉得l对是严谨的Q!q个变量的值是1Q表明是可以用的I间Q只是这里我想了惻I如果把它改ؓ0或者是其他g知道会发生什么事Q!但是有一Ҏ可以肯定Q就是释攄对不会那么顺利进行!因ؓq是一个标讎ͼ
当然Q这里可能还是有Z有疑问,Z么这样就可以释放呢?Q我刚才也有q个疑问。后来我惛_Q释放是操作pȝ的事Q那么就free()q个源代码来看,什么也没有释放Q对吧?但是它确实是定了管理信息的那块内存的内宏V所以,free()只是记录了一些信息,然后告诉操作pȝ那块内存可以去释放,具体怎么告诉操作pȝ的我不清楚,但我觉得q个已经出了我q篇文章的讨围了?/p>
那么Q我之前有个错误的认识,是认ؓ指向那块内存的指针不移到那块内存中的哪个位|都可以释放那块内存Q但是,q是大错牚wQ释放是不可以释放一部分的!首先q点应该要明白。而且Q从free()的源代码看,ptr只能指向可用I间的首地址Q不Ӟ减去l构体大之后一定不是指向管理信息空间的首地址。所以,要确保指针指向可用空间的首地址Q不信吗Q自己可以写一个程序然后移动指向可用空间的指针Q看E序会有会崩Q?/p>
最后可能想到malloc()的源代码看看malloc()到底是怎么分配I间的,q里面涉及到很多其他斚w的知识!有兴的朋友可以自己M载源
代码ȝ看?/p>
四、关于其他:
关于C中的malloc()和free()的讨论就写到q里吧!写了三个钟头Q感觉有点篏Q希望对大家有所帮助Q有不对的地Ҏq大家指出!最后,谢谢参与q个帖子讨论的所有朋友,帖子Q?a >http://www.bc-cn.net/bbs/dispbbs.asp?boardID=5&ID=81781&page=1?br>
有了malloc/freeZ么还要new/delete Q?br> malloc与free是C++/C语言的标准库函数Qnew/delete是C++的运符。它们都可用于申请动态内存和释放内存?br> |
1 size_t strlen_a(const char * str) {
2 size_t length = 0 ;
3 while (*str++ )
4 ++ length;
5 return length;
6 }
也许可以E加改进如下Q?/p>
1 size_t strlen_b(const char * str) {
2 const char *cp = str;
3 while (*cp++ )
4 ;
5 return (cp - str - 1 );
6 }
本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/robinfoxnan/archive/2008/07/25/2712030.aspx
class String
{
public:
String(const char *str=NULL); //构造函?/span>
String(const String &other); //拯构造函?/span>
~String(void); //析构函数
String& operator=(const String &other); //{号操作W重?/span>
ShowString();
String::~String()
{
delete [] m_data; //析构函数Q释攑֜址I间
}
String::String(const char *str)
{
if (str==NULL)//当初始化串不存在的时候,?/span>m_data甌一个空间存?/span>'\0'Q?/span>
{
m_data=new char[1];
*m_data='\0';
}
else//当初始化串存在的时候,?/span>m_data甌同样大小的空间存放该Ԍ
{
int length=strlen(str);
m_data=new char[length+1];
strcpy(m_data,str);
}
}
String::String(const String &other)//拯构造函敎ͼ功能与构造函数类伹{?/span>
{
int length=strlen(other.m_data);
m_data=new [length+1];
strcpy(m_data,other.m_data);
}
String& String::operator =(const String &other)
{
if (this==&other)//当地址相同Ӟ直接q回Q?/span>
return *this;
delete [] m_data;//当地址不相同时Q删除原来申LI间Q重新开始构造;
int length=sizeof(other.m_data);
m_data=new [length+1];
strcpy(m_data,other.m_data);
return *this;
}
String::ShowString()//׃m_data是私有成员,对象只能通过public成员函数来访问;
{
cout<<this->m_data<<endl;
}
main()
{
String AD;
char * p="ABCDE";
String B(p);
AD.ShowString();
AD=B;
AD.ShowString();
}
class String
{
public:
String(const char *str=NULL); //构造函?/span>
String(const String &other); //拯构造函?/span>
~String(void); //析构函数
String& operator=(const String &other); //{号操作W重?/span>
ShowString();
String::~String()
{
delete [] m_data; //析构函数Q释攑֜址I间
}
String::String(const char *str)
{
if (str==NULL)//当初始化串不存在的时候,?/span>m_data甌一个空间存?/span>'\0'Q?/span>
{
m_data=new char[1];
*m_data='\0';
}
else//当初始化串存在的时候,?/span>m_data甌同样大小的空间存放该Ԍ
{
int length=strlen(str);
m_data=new char[length+1];
strcpy(m_data,str);
}
}
String::String(const String &other)//拯构造函敎ͼ功能与构造函数类伹{?/span>
{
int length=strlen(other.m_data);
m_data=new [length+1];
strcpy(m_data,other.m_data);
}
String& String::operator =(const String &other)
{
if (this==&other)//当地址相同Ӟ直接q回Q?/span>
return *this;
delete [] m_data;//当地址不相同时Q删除原来申LI间Q重新开始构造;
int length=sizeof(other.m_data);
m_data=new [length+1];
strcpy(m_data,other.m_data);
return *this;
}
String::ShowString()//׃m_data是私有成员,对象只能通过public成员函数来访问;
{
cout<<this->m_data<<endl;
}
main()
{
String AD;
char * p="ABCDE";
String B(p);
AD.ShowString();
AD=B;
AD.ShowString();
}
强制转化四种cd可能很多人都常常忽略p我一P但是有时q是比较有用的。不了解的徏议看看,一些机制我也不是十分了解,只是一些用法写出来让大家看看?br> 2004-11-27 9:00
强制转化无论从语法还是语意上看,都是c++中最隄的特征之一。但是基于c风格的{化的语义的不明确性及其一些潜在问题。强制类型{化最l还是被c++接受了?br>1.static_castq算W号
static_cast<T>(e),stroustrup让我们可以把它看成隐含{换的昄的逆运。这个是有一定道理的Q基于隐式{化的对象cd我们可以使用static_cast转化q算W号。它是静态的,无法q行时检类型,在承中ؓH出?br>使用范围
<1>用于所有系l类型之间{化,不能用于pȝcd指针cd转化
double t_d = 0;
int t_i= static_cast<int>(t_d); //是合法的转化
而企囑ְdouble*->int*是不允许?br><2>用于l承cM间的转化Q含指针Q,不能用于其他没有隐式转化的对象类型之间的转化
l承举例:
class x
{
};
class y: public x
{
};
使用:x t_o_x;
y t_o_y = static_cast<y>(t_o_x); //x* y*转化也可以进行因为x,yl承?br>//p,cd可以自动隐式转化使用
隐式转化举例:
class x
{
};
class y
{
public:
y( x i_x ) {}
};
x t_o_x;
y t_o_y = static_cast<y>(t_o_x); //大家看到y构造函数可以对于xcd隐式转化
//所以可以将x->yQ如果企囑ְy->x会报?br>2.reinterpret_cast q算
主要用于对于cd指针cd的强制{化,some_type* -> special_type*q样转化Q类型信息可以是不完全的。它允许Q意指针{化到其他cd指针Q也允许L整数cdCQ意指针类型{?BT)。这样导致的l果是极其不安全的,不能安全的应用于其他目的Q除非{化到原来cd?br><1> 使用所有整形可以{化ؓLcd的指?指针?字节的long的东东,那么机器p为同cd是可以转化)
int c;
x* p = reinterpret_cast<x*>(c); //x是自定义的Q意类型,当然包括pȝcd
<2> 可以对于Lcd指针之间转化
y* c;
x* p = reinterpret_cast<x*>(c);//x,y代表所有自定义或系l类?br>大家可以看到reinterpret_cast的{化是极度的不负责ȝQ他只管转化不检是否可以{化?br><3> const_castq算W号
q个很简单从名字大家可以看出来,仅仅ZL或着加上const修饰W号。但是对于本w定义时为const的类型,即你去掉const性,在你操作q片内容时候也要小心,只能r不能w操作Q否则还是会出错?br>const char* p = "123";
char* c = const_cast<char*>(p);
c[0] = 1; //表面上通过~译L了const性,但是操作其地址时系l依然不允许q?br>//么做。这是一个漏z吧
<4> dynamic_castq算W号
Scott Mayers其描述为用来执行承体pMQ安全的向下转型或者跨p{型动作。也是说你可以Q用dynamic_cast?指向base class的指针或引用转型?指向子类的对象的指针或引用?br>class B {}; //polymorphiccd含virtual才能dynamic_cast
class D: public B {}
void f( B* pb )
{
D* pd1 = dynamic_cast<D*>(pb);//如果pb为dcd正确q回Q如果不是返?
D* pd2 = static_cast<D*>(pb); //不管怎么样都q回指针有可能指向不合适的?br>//象,因ؓstatic仅仅静态检,不能得到q?br>//行时对象的信息是否真正ؓDcd
}
static_cast<>揭密
作者:Sam NG
译者:刀?/a>
原文链接Q?a >What static_cast<> is actually doing
本文讨论static_cast<> ?reinterpret_cast<>?
介绍
大多E序员在学C++前都学过CQƈ且习惯于C风格Q类型)转换。当写C++Q程序)Ӟ有时候我们在使用static_cast<>?reinterpret_cast<>时可能会有点模糊。在本文中,我将说明static_cast<>实际上做了什么,q且指出一些将会导致错误的情况?br>
泛型QGeneric TypesQ?/strong>
float f = 12.3;而言之,static_cast<> 尝试{换,举例来说Q如float-?integerQ而reinterpret_cast<>单改变编译器的意N新考虑那个对象作ؓ另一cd?br>
float* pf = &f;
// static cast<>
// 成功~译, n = 12
int n = static_cast<int>(f);
// 错误,指向的类型是无关的(译注Q即指针变量pf是floatcdQ现在要被{换ؓintcdQ?br> //int* pn = static_cast<int*>(pf);
//成功~译
void* pv = static_cast<void*>(pf);
//成功~译, 但是 *pn2是无意义的内存(rubbishQ?br>
int* pn2 = static_cast<int*>(pv);
// reinterpret_cast<>
//错误,~译器知道你应该调用static_cast<>
//int i = reinterpret_cast<int>(f);
//成功~译, 但是 *pn 实际上是无意义的内存,?*pn2一?br>
int* pi = reinterpret_cast<int*>(pf);
class CBaseX情况1Q两个无关的cM间的转换
{
public:
int x;
CBaseX() { x = 10; }
void foo() { printf("CBaseX::foo() x=%d\n", x); }
};
class CBaseY
{
public:
int y;
int* py;
CBaseY() { y = 20; py = &y; }
void bar() { printf("CBaseY::bar() y=%d, *py=%d\n", y, *py);
}
};
class CDerived : public CBaseX, public CBaseY
{
public:
int z;
};
// Convert between CBaseX* and CBaseY*正如我们在泛型例子中所认识到的Q如果你试转换一个对象到另一个无关的cstatic_cast<>失败,而reinterpret_cast<>L成功“ƺ骗”~译器:那个对象是那个无关cR?br>
// CBaseX* ?CBaseY*之间的{?br>
CBaseX* pX = new CBaseX();
// Error, types pointed to are unrelated
// 错误Q?cd指向是无关的
// CBaseY* pY1 = static_cast<CBaseY*>(pX);
// Compile OK, but pY2 is not CBaseX
// 成功~译, 但是 pY2 不是CBaseX
CBaseY* pY2 = reinterpret_cast<CBaseY*>(pX);
// System crash!!
// pȝ崩溃!!
// pY2->bar();
1. CDerived* pD = new CDerived();
2. printf("CDerived* pD = %x\n", (int)pD);
3.
4. // static_cast<> CDerived* -> CBaseY* -> CDerived*
//成功~译Q隐式static_cast<>转换
5. CBaseY* pY1 = pD;
6. printf("CBaseY* pY1 = %x\n", (int)pY1);
// 成功~译, 现在 pD1 = pD
7. CDerived* pD1 = static_cast<CDerived*>(pY1);
8. printf("CDerived* pD1 = %x\n", (int)pD1);
9.
10. // reinterpret_cast
// 成功~译, 但是 pY2 不是 CBaseY*
11. CBaseY* pY2 = reinterpret_cast<CBaseY*>(pD);
12. printf("CBaseY* pY2 = %x\n", (int)pY2);
13.
14. // 无关?static_cast<>
15. CBaseY* pY3 = new CBaseY();
16. printf("CBaseY* pY3 = %x\n", (int)pY3);
// 成功~译,管 pY3 只是一?"?CBaseY()"
17. CDerived* pD3 = static_cast<CDerived*>(pY3);
18. printf("CDerived* pD3 = %x\n", (int)pD3);
---------------------- 输出 ---------------------------
CDerived* pD = 392fb8
CBaseY* pY1 = 392fbc
CDerived* pD1 = 392fb8
CBaseY* pY2 = 392fb8
CBaseY* pY3 = 390ff0
CDerived* pD3 = 390fec
注意Q在CDerived*用隐?static_cast<>转换到CBaseY*Q第5行)Ӟl果是(指向QCDerived*Q的指针向后Q?偏移?Q个字节Q(译注Q?为intcd在内存中所占字节数Q。ؓ了知道static_cast<> 实际如何Q我们不得不要来看一下CDerived的内存布局?/p>
CDerived的内存布局QMemory LayoutQ?/strong>
如图所C,CDerived的内存布局包括两个对象QCBaseX ?CBaseYQ编译器也知道这一炏V因此,当你CDerived* 转换?CBaseY*Ӟ它给指针d4个字节,同时当你CBaseY*转换到CDerived*Ӟ它给指针减去4。然而,甚至它即便不是一个CDerived你也可以q样做?br>当然Q这个问题只在如果你做了多承时发生。在你将CDerived转换 ?CBaseX时static_cast<> ?reinterpret_cast<>是没有区别的?br>
情况3Qvoid*之间的向前和向后转换
因ؓM指针可以被{换到void*Q而void*可以被向后{换到M指针Q对于static_cast<> ?reinterpret_cast<>转换都可以这样做Q,如果没有心处理的话错误可能发生?br>
CDerived* pD = new CDerived();
printf("CDerived* pD = %x\n", (int)pD);
CBaseY* pY = pD; // 成功~译, pY = pD + 4
printf("CBaseY* pY = %x\n", (int)pY);
void* pV1 = pY; //成功~译, pV1 = pY
printf("void* pV1 = %x\n", (int)pV1);
// pD2 = pY, 但是我们预期 pD2 = pY - 4
CDerived* pD2 = static_cast<CDerived*>(pV1);
printf("CDerived* pD2 = %x\n", (int)pD2);
// pȝ崩溃
// pD2->bar();
---------------------- 输出 ---------------------------
CDerived* pD = 392fb8
CBaseY* pY = 392fbc
void* pV1 = 392fbc
CDerived* pD2 = 392fbc
一旦我们已l{换指针ؓvoid*Q我们就不能L其转换回原cR在上面的例子中Q从一个void* q回CDerived*的唯一Ҏ是将其{换ؓCBaseY*然后再{换ؓCDerived*?
但是如果我们不能定它是CBaseY* q是 CDerived*Q这时我们不得不用dynamic_cast<> 或typeid[2]?br>
注释Q?/strong>
1. dynamic_cast<>Q从另一斚w来说Q可以防止一个泛型CBaseY* 被{换到CDerived*?br>2. dynamic_cast<>需要类成ؓ多态,卛_?#8220;?#8221;函数Qƈ因此而不能成为void*?br>参考:
1. [MSDN] C++ Language Reference -- Casting
2. Nishant Sivakumar, Casting Basics - Use C++ casts in your VC++.NET programs
3. Juan Soulie, C++ Language Tutorial: Type Casting
推荐链接Q?/strong>如何在运行时定对象cdQRTTIQ?/a>