??xml version="1.0" encoding="utf-8" standalone="yes"?>
C计算Z内存I间都是按照byte划分的,从理Z讲似乎对Mcd的变量的讉K可以从Q何地址开始,但实际情冉|在访问特定类型变量的时候经常在?
定的内存地址讉KQ这需要各U类型数据按照一定的规则在空间上排列Q而不是顺序的一个接一个的排放Q这是寚w?br />
寚w的作用和原因Q各个硬件^台对存储I间的处理上有很大的不同。一些^台对某些特定cd的数据只能从某些特定地址开始存取。比如有些架构的CPU在访?
一个没有进行对齐的变量的时候会发生错误,那么在这U架构下~程必须保证字节寚w.其他q_可能没有q种情况Q但是最常见的是如果不按照适合其^台要求对
数据存放q行寚wQ会在存取效率上带来损失。比如有些^台每ơ读都是从偶地址开始,如果一个int型(假设?2位系l)如果存放在偶地址开始的地方Q那
么一个读周期可以读32bitQ而如果存攑֜奇地址开始的地方Q就需?个读周期Qƈ对两ơ读出的l果的高低字节进行拼凑才能得到该32bit?
据。显然在d效率上下降很多?/p> 先让我们看几个例子吧(32bit,x86环境,gcc~译?: l构体A中包含了4字节长度的int一个,1字节长度的char一个和2字节长度的short型数据一?B也一?按理说A,B大小应该都是7字节?br />之所以出C面的l果是因为编译器要对数据成员在空间上q行寚w。上面是按照~译器的默认讄q行寚w的结?那么我们是不是可以改变编译器的这U默认对齐设|呢,当然可以.例如: 先让我们看四个重要的基本概念Q?br />1.数据cd自n的对齐| 1.在VC IDE中,可以q样修改Q[Project]|[Settings],c/c++选项卡Category的Code Generation选项的Struct Member Alignment中修改,默认?字节?br />2.在编码时Q可以这样动态修改:#pragma pack .注意:是pragma而不是progma. 代码中关于对齐的隐患Q很多是隐式的。比如在强制cd转换的时候。例如: p=&i; 如果出现寚w或者赋值问题首先查?br />1. ~译器的big little端设|?br />2. 看这U体pLw是否支持非寚w讉K ?相关文章:转自http://blog.csdn.net/goodluckyxl/archive/2005/10/17/506827.aspx ARM下的寚w处理 3.13 type qulifiers 有部分摘自ARM~译器文档对齐部?/p> 寚w的? p = (char*)&a; /* 当高U语a函数被编译成机器码时Q有一个问题就必须解决Q因为CPU没有办法知道一个函数调用需要多个、什么样的参数。即计算Z知道怎么l这个函C递参敎ͼ传递参数的工作必须由函数调用者和函数本n来协?/font>。ؓ此,计算机提供了一U被UCؓ栈的数据l构来支持参C递? 函数调用Ӟ调用者依ơ把参数压栈Q然后调用函敎ͼ函数被调用以后,在堆栈中取得数据Qƈq行计算。函数计结束以后,或者调用者、或者函数本w修改堆栈,使堆栈恢复原装。在参数传递中Q有两个很重要的问题必须得到明确说明Q?/p>
1) 当参C数多于一个时Q按照什么顺序把参数压入堆栈Q?br />2) 函数调用后,p来把堆栈恢复原装?br />3Q函数的q回值放在什么地?/font> stdcall
很多时候被UCؓpascal调用规范Q因为pascal是早期很常见的一U教学用计算机程序设计语aQ其语法严}Q用的函数调用U定是stdcall?
在Microsoft C++pd的C/C++~译器中Q常常用PASCAL宏来声明q个调用U定Q类似的宏还有WINAPI和CALLBACK? stdcall调用规范声明的语法ؓQ?/p> 而在~译Ӟq个函数的名字被译成_function@8 注意不同~译器会插入自己的汇~代码以提供~译的通用性,但是大体代码如此。其中在函数开始处保留esp到ebp中,在函数结束恢复是~译器常用的Ҏ? 从函数调用看Q??依次被pushq堆栈,而在函数中又通过相对于ebp(卛_q函数时的堆栈指针)的偏U量存取参数。函数结束后Qret 8表示清理8个字节的堆栈Q函数自己恢复了堆栈? cdecl调用U定又称为C调用U定Q是C语言~省的调用约定,它的定义语法是:
cdecl调用U定的参数压栈顺序是和stdcall是一LQ参数首先由有向左压入堆栈。所不同的是Q函数本w不清理堆栈Q调用者负责清理堆栈。由于这
U变化,C调用U定允许函数的参数的个数是不固定的,q也是C语言的一大特艌Ӏ对于前面的function函数Q用cdecl后的汇编码变成: MSDN中说Q该修饰自动在函数名前加前导的下划线Q因此函数名在符可中被记录为_function? ׃参数按照从右向左序压栈Q因此最开始的参数在最接近栈顶的位|,因此当采用不定个数参数时Q第一个参数在栈中的位|肯定能知道Q只要不定的参数个数能够ҎW一个后者后l的明确的参数确定下来,可以用不定参敎ͼ例如对于sprintf函数Q定义ؓQ?/p> thiscall是唯一一个不能明指明的函数修饰Q因为thiscall不是关键字。它是C++cL员函数缺省的调用U定。由于成员函数调用还有一个this指针Q因此必ȝD处理,thiscall意味着Q? C++资源之不完全导引Q完整版Q?/p>
来源Q?a >www.csdn.net 撰文Q曾毅、陶?/p>
声明Q本?004q?月首发于《CSDN开发高手》,版权归该杂志与《程序员》杂志社 ------------------------------------------------------------------------ 1Q前a 无数ơ听到“我要开始学习C++!”的呐喊Q无数次听到“C++太复杂了Q我真的 撰写本文的初衷ƈ不打带领大家体验古老的C++历史Q如果你想了解C++的历 本文介绍q分析了一些编译器Q开发环境,库,量的书c以及参考网站,q?br />且尽可能试着l出一个利用这些资源的导引Q望对如同我们一L初学者能够有 ------------------------------------------------------------------------ 2Q编译器 在C++之外的Q何语a中,~译器都从来没有受到q如此之重视。因为C++是一 2.1 Borland C++ q个是Borland C++ Builder和Borland C++ Builder Xq两U开发环境的后台 2.2 Visual C++ q个正是我们熟知的Visual Studio ?Visual Studio.net 2002, 2003以及2 2.3 GNU C++ 著名的开源C++~译器。是cUnix操作pȝ下编写C++E序的首选。特Ҏ有非 ZGNU C++的编译器有很多,比如Q?/p>
(1) Mingw GCC的一个Windows的移植版本(Dev-C++的后収ͼ (2) Cygwin http://sources.redhat.com/cygwin/ GCC的另外一个WindowsUL版本是Cygwin的一部分QCygwin是Windows下的一?br />Unix仿真环境。严格的说是模拟GNU的环境,q也是"Gnu's Not Unix"要表辄?br />思,噢,扯远了,qƈ不是我们在这里关心的实质内容?/p>
(3) Djgpp q是GCC的DOSUL版本?/p>
(4) RSXNT http://www.mathematik.uni-bielefeld.de/~rainer/ q是GCC的DOS和WindowsUL版本?/p>
(5) Intel C++ 著名CPU刉厂商Intel出品的编译器QSpecial Design for Intel x86Q对?br />Intel x86l构的CPUl过特别的优化。在有些应用情况下,特别是数D等高?br />能应用,仅仅采用Intel的编译器~译p大幅度的提高性能?/p>
(6) Digital Mars C++ |络上提供免费下载,Zortech/Symantec C++的承者,其前w在当年惨烈?br />C++四国战中也是主角之一?/p>
------------------------------------------------------------------------ 3Q开发环?/p>
开发环境对于程序员的作用不a而喻。选择自己朝夕相处的环境也不是Ҏ?br />事情Q特别是在IDE如此丰富的情况下。下面就是我们推荐的一些常见的C++开发环 3.1 Visual Studio 6.0 q个虽然是Microsoft公司的老版本的开发环境,但是鉴于其后l版本Visual 3.2 Visual Studio.NET 2003 作ؓMicrosoft公司官方正式发布的最新版本开发环境,其中有太多激动h心的 3.3 Borland C++ Builder 6 q个q不是Borland的C++开发环境的最新版本。选择它的原因是它不是用Java 3.4 Borland C++ Builder X 正如前文所qͼ虽然版本号上和前面那个IDE非常相象Q但是其实它们是完全?br />同的两个集成开发环境。C++Builder更多的是一个和Delphi同步的C++版本的开发环 3.5 Emacs + GCC 前面讲的大部分是Windows环境下的集成开发环境。Linux上的开发者更們?br />使用Emacs来编辑C++的文Ӟ用Makefile来命令GCC做编译。虽然看上去比较松散Q?br />但是q些东西l合hq是一个开0发环境。如果你能够娴熟的用这L环境写程 3.6 Dev C++ GCC是一个很好的~译器。在Windows上的C++~译器一直和标准有着一D距ȝ 3.7 Eclipse + CDT Eclipse可是q来大名鼎鼎的开发工兗最C期的Jolt大奖颁l了q个杰出 ------------------------------------------------------------------------ 4Q工?/p>
C++的辅助工L多,我们分门别类的ؓ大家作介l: 4.1 文档c?/p>
(1) Doxygen Doxygen是一U适合C风格语言Q如C++、C、IDL、Java甚至包括C#和PHPQ的?br />开放源码的、基于命令行的文档生器?/p>
(2) C++2HTML 参考站点:http://www.bedaux.net/cpp2html/ 把C++代码变成语法高亮的HTML (3) CodeColorizer 参考站点:http://www.chami.com/colorizer/ 它能把好几种语言的源代码着色ؓHTML (4) Doc-O-Matic 参考站点:http://www.doc-o-matic.com/ Doc-O_MaticZ的C/C++QC++.netQDelphi/Pascal, VB.NETQC#和JavaE序 (5) DocVizor 参考站点:http://www.ucancode.net/Products/DocBuilder/Features.htm DocVizor满了面向对象Y件开发者的基本要求——它让我们能够看到C++工程 (6) SourcePublisher C++ 参考站点:http://www.scitools.com/sourcepublisher_c.html l源代码产生提供快速直观的HTML报表Q包括代码,cdơ结构,调用和被?br />用树Q包含和被包含树。支持多U操作系l?/p>
(7) Understand 参考站点:http://www.scitools.com/ucpp.html 分析M规模的C或者C++工程Q帮助我们更好的理解以及~写文档?/p>
4.2 代码c?/p>
(1) CC-Rider CC-Rider是用于C/C++E序强大的代码可视化工具Q通过交互式浏览、编辑及?br />动文件来促进E序的维持和发展?/p>
(2) CodeInspect 一U新的C/C++代码分析工具。它查我们的源代码找出非标准的,可能的,?br />及普通的错误代码?/p>
(3) CodeWizard 先进的C/C++源代码分析工P使用过500个编码规范自动化地标明危险的Q?br />但是~译器不能检查到的代码结构?/p>
(4) C++ Validation Test Suites 参考站点:http://www.plumhall.com/suites.html 一l用于测试编译器和库对于标准dE度的代码库?/p>
(5) CppRefactory 参考站点:http://cpptool.sourceforge.net/ CPPRefactory是一个得开发者能够重构他们的C++代码的程序。目的是使得C (6) Lzz 参考站点:http://www.lazycplusplus.com/ Lzz是一个自动化许多C++~程中的体力zȝ工具。它能够节省我们许多事gq?br />且得编码更加有乐趣。给Zpd的声明,Lzz会给我们创徏头文件和源文件?/p>
(7) QA C++ Generation 2000 参考站点:http://www.programmingresearch.com/solutions/qacpp.htm 它关注面向对象的C++源代码,Ҏ关于设计Q效率,可靠性,可维护性的部分 (8) s-mail project - Java to C++DOL 参考站点:http://sadlocha.strefa.pl/s-mail/ja2dol.html 把Java源代码翻译ؓ相应的C++源代码的命o行工兗?/p>
(9) SNIP from Cleanscape Software International 参考站点:http://www.cleanscape.net/stdprod/snip/index.html 一个填q编码和设计之间沟壑的易于用的C++开发工P节省大量~辑和调?br />的事Ӟ它还使得开发者能够指定设计模式作为对象模型,自动从对象模型中产生 (10) SourceStyler C++ 参考站点:http://www.ochresoftware.com/ 对C/C++源代码提供完整的格式化和排版控制的工兗提供多?5个的格式化?br />以及完全支持ANSI C++?/p>
4.3 ~译c?/p>
(1) Compilercache 参考站点:http://www.erikyyy.de/compilercache/ Compilercache是一个对你的C和C++~译器的装脚本。每ơ我们进行编译,?br />装脚本,把编译的l果攑օ~存Q一旦编译相同的东西Q结果将从缓存中取出而不 (2) Ccache Ccache是一个编译器~存。它使用h像C/C++~译器的~存预处理器Q编?br />速度通常能提高普通编译过E的5~10倍?/p>
(3) Cmm (C++ with MultiMethods) 参考站点:http://www.op59.net/cmm/cmm-0.28/users.html q是一UC++语言的扩展。读入Cmm源代码输出C++的源代码Q功能是对C++语言 (4) The Frost Project Forst使得你能够在C++E序中像原生的C++Ҏ一样用multimethod以及虚函 4.4 试和调试类 (1) CPPUnit CppUnit 是个Z LGPL 的开源项目,最初版本移植自 JUnitQ是一个非怼 (2) C++Test C++ Test是一个单元测试工P它自动化了C和C++c,函数或者组件的试?/p>
参考站点:http://www.iplbath.com/products/tools/pt400.shtml 设计的目的是Z满在合理的l济开销下用这个工具可以让开发工E师开 (4) Purify 参考站点:http://www-900.ibm.com/cn/software/rational/products/purif IBM Rational PurifyPlus是一套完整的q行时分析工P旨在提高应用E序?br />可靠性和性能。PurifyPlus内存错误和泄漏、应用程序性能描述、代码覆?br />分析{功能组合在一个单一、完整的工具包中?/p>
(5) BoundsChecker BoundsChecker是一个C++q行旉误检和调试工具。它通过在Visual Studi 一个自动化的运行时E序试工具Q检查难以察觉的错误,如内存覆盖,内存?br />漏,内存分配错误Q变量初始化错误Q变量定义冲H,指针错误Q库错误Q逻辑?br />误和法错误{?/p>
(7) GlowCode GlowCode包括内存泄漏查,code profilerQ函数调用跟t等功能。给C++开 (8) Stack Spy 参考站点:http://www.imperioustech.com/ 它能捕捉stack corruption, stack over run, stack overflow{有x的错 ------------------------------------------------------------------------ 5Q库 在C++中,库的C是非帔R的。C++之父 Bjarne Stroustrup先生多次表示?br />设计库来扩充功能要好q设计更多的语法的言论。现实中QC++的库门类J多Q解?br />的问题也是极其广泛,库从轻量U到重量U的都有。不都是让人眼界大开Q亦?br />是望而生叹的思维C。由于库的数量非常庞大,而且限于W者水qI其中很多q?br />不了解。所以文中所提的一些库都是比较著名的大型库?/p>
5.1 标准?/p>
标准库中提供了C++E序的基本设施。虽然C++标准库随着C++标准折腾了许多年 (1) Dinkumware C++ Library 参考站点:http://www.dinkumware.com/ P.J. Plauger~写的高品质的标准库。P.J. Plauger博士是Dr. Dobb'sE序?br />计杰出奖的获得者。其~写的库长期被Microsoft采用Qƈ且最qBorland也取得了 (2) RogueWave Standard C++ Library 参考站点:http://www.roguewave.com/ q个库在Borland C++ Builder的早期版本中曄被采用,后来被其他的库给?br />换了。笔者不推荐使用?/p>
(3) SGI STL 参考站点:http://www.roguewave.com/ SGI公司的C++标准模版库?/p>
(4) STLport SGI STL库的跨^台可UL版本?/p>
5.2 “准”标准库 - Boost 参考站点:http://www.boost.org 国内镜像Q?a >http://www.c-view.org/tech/lib/boost/index.htm Boost库是一个经q千锤百点{可UL、提供源代码的C++库,作ؓ标准库的?br />备,是C++标准化进E的发动Z一?Boost库由C++标准委员会库工作l成员发?br />Q在C++C中媄响甚大,其成员已q?000人?Boost库ؓ我们带来了最新、最酗?br />最实用的技术,是不折不扣的“准”标准库?/p>
Boost中比较有名气的有q么几个库: Regex 正则表达式库 Spirit LL parser frameworkQ用C++代码直接表达EBNF Graph 囄件和法 Lambda 在调用的地方定义短小匿名的函数对象,很实用的functional功能 concept check 查泛型编E中的concept Mpl 用模板实现的元编E框?/p>
Thread 可移植的C++多线E库 Python 把C++cd函数映射到Python之中 Pool 内存池管?/p>
smart_ptr 5个智能指针,学习指针必读Q一份不错的参考是来自CUJ的文章: Smart Pointers in BoostQ哦Q这文章可以查刎ͼCUJ是提供在U浏览的?br />中文版见W者在《Dr. Dobb's Journal软g研发杂志》第7辑上的译文?/p>
BoostM来说是实用h值很高,质量很高的库。ƈ且由于其对跨q_的强调, 5.3 GUI 在众多C++的库中,GUI部分的库是比较J荣Q也比较引h注目的。在实际开 (1) MFC 大名鼎鼎的微软基cdQMicrosoft Foundation ClassQ。大凡学qVC++?br />人都应该知道q个库。虽然从技术角度讲QMFC是不大漂亮的Q但是它构徏于Windo (2) QT 参考网站:http://www.trolltech.com/ Qt是Trolltech公司的一个多q_的C++囑Ş用户界面应用E序框架。它提供l?br />应用E序开发者徏立艺术的图形用L面所需的所用功能。Qt是完全面向对象的 (3) WxWindows 参考网站:http://www.wxwindows.org/ 跨^台的GUI库。因为其cdơ极像MFCQ所以有文章介绍从MFC到WxWindows?br />代码UL以实现跨q_的功能。通过多年的开发也是一个日完善的GUI库,支持?br />样不׃前面两个库。ƈ且是完全开放源代码的。新q的C++ Builder X的GUI设计 (4) Fox 参考网站:http://www.fox-toolkit.org/ 开放源代码的GUI库。作者从自己亲n的开发经验中得出了一个理想的GUI库应
ZATL的一个库。因Z用了大量ATL的轻量手法Q模板等技术,在代码尺 (6) GTK 参考网站:http://gtkmm.sourceforge.net/ GTK是一个大名鼎鼎的C的开源GUI库。在Linux世界中有Gnomeq样的杀手应用?br />而GTK是q个库的C++装版本?/p>
5.4 |络通信 (1) ACE 参考网站:http://www.cs.wustl.edu/~schmidt/ACE.html C++库的代表Q超重量U的|络通信开发框架。ACE自适配通信环境QAdaptive (2) StreamModule 参考网站:http://www.omnifarious.org/StrMod/ 设计用于化编写分布式E序的库。尝试着使得~写处理异步行ؓ的程序更?br />易,而不是用同步的外壛_起异步的本质?/p>
(3) SimpleSocket 参考网站:http://home.hetnet.nl/~lcbokkers/simsock.htm q个cd让编写基于socket的客?服务器程序更加容易?/p>
(4) A Stream Socket API for C++ 参考网站:http://www.pcs.cnu.edu/~dgame/sockets/socketsC++/sockets.h 又一个对Socket的封装库?/p>
5.5 XML (1) Xerces 参考网站:http://xml.apache.org/xerces-c/ Xerces-C++ 是一个非常健壮的XML解析器,它提供了验证Q以及SAX和DOM API (2) XMLBooster 参考网站:http://www.xmlbooster.com/ q个库通过产生特制的parser的办法极大的提高了XML解析的速度Qƈ且能够 (3) Pull Parser 参考网站:http://www.extreme.indiana.edu/xgws/xsoap/xpp/ q个库采用pullҎ的parser。在每个SAX的parser底层都有一个pull的parse
参考网站:http://xml.apache.org/xalan-c/ Xalan是一个用于把XML文档转换为HTMLQ纯文本或者其他XMLcd文档的XSLT?br />理器?/p>
(5) CMarkup 参考网站:http://www.firstobject.com/xml.htm q是一U用EDOM的XML解析器。在很多思\上面非常灉|实用。值得大家在D (6) libxml++ http://libxmlplusplus.sourceforge.net/ libxml++是对著名的libxml XML解析器的C++装版本 5.6 U学计算 (1) Blitz++ 参考网站:http://www.oonumerics.org/blitz/ Blitz++ 是一个高效率的数D函数库Q它的设计目的是希望建立一套既?br />像C++ 一h便,同时又比Fortran速度更快的数D环境。通常Q用C++所写出 (2) POOMA 参考网站:http://www.codesourcery.com/pooma/pooma POOMA是一个免费的高性能的C++库,用于处理q行式科学计。POOMA的面向对 (3) MTL 参考网站:http://www.osl.iu.edu/research/mtl/ Matrix Template Library(MTL)是一个高性能的泛型组件库Q提供了各种格式 (4) CGAL 参考网站:www.cgal.org Computational Geometry Algorithms Library的目的是把在计算几何斚w的大 5.7 游戏开?/p>
(1) Audio/Video 3D C++ Programming Library 参考网站:http://www.galacticasoftware.com/products/av/ ***3D是一个跨q_Q高性能的C++库。主要的Ҏ是提供3D囑ŞQ声效支持(S (2) KlayGE 参考网站:http://home.g365.net/enginedev/ 国内游戏开发高手自qC++开发的游戏引擎。KlayGE是一个开放源代码、跨q?br />台的游戏引擎Qƈ使用Python作脚本语a。KlayGE在LGPL协议下发行。感谢龚敏敏 (3) OGRE OGREQ面向对象的囑Ş渲染引擎Q是用C++开发的Q用灵zȝ面向对象3D引擎 5.8 U程 (1) C++ Threads 参考网站:http://threads.sourceforge.net/ q个库的目标是给E序员提供易于用的c,q些c被l承以提供在Linux环境 (2) ZThreads 参考网站:http://zthread.sourceforge.net/ 一个先q的面向对象Q跨q_的C++U程和同步库?/p>
5.9 序列?/p>
(1) s11n 参考网站:http://s11n.net/ 一个基于STL的C++库,用于序列化PODQSTL容器以及用户定义的类型?/p>
(2) Simple XML Persistence Library 参考网站:http://sxp.sourceforge.net/ q是一个把对象序列化ؓXML的轻量的C++库?/p>
5.10 字符?/p>
(1) C++ Str Library 参考网站:http://www.utilitycode.com/str/ 操作字符串和字符的库Q支持Windows和支持gcc的多U^台。提供高度优化的 (2) Common Text Transformation Library 参考网站:http://cttl.sourceforge.net/ q是一个解析和修改STL字符串的库。CTTL substringcd以用来比较,插入Q?br />替换以及用EBNF的语法进行解析?/p>
(3) GRETA 参考网站:http://research.microsoft.com/projects/greta/ q是由微软研I的研Ih员开发的处理正则表达式的库。在型匚w的情?br />下有非常优秀的表现?/p>
5.11 l合 (1) P::Classes 参考网站:http://pclasses.com/ 一个高度可UL的C++应用E序框架。当前关注类型和U程安全的signal/slot (2) ACDK - Artefaktur Component Development Kit 参考网站:http://acdk.sourceforge.net/ q是一个^台无关的C++lg框架Q类gJava或?NET中的框架Q反机Ӟ (3) dlib C++ library 参考网站:http://www.cis.ohio-state.edu/~kingd/dlib/ 各种各样的类的一个综合。大整数QSocketQ线E,GUIQ容器类,以及览?br />录的API{等?/p>
(4) Chilkat C++ Libraries 参考网站:http://www.chilkatsoft.com/cpp_libraries.asp q是提供zipQe-mailQ编码,S/MIMEQXML{方面的库?/p>
(5) C++ Portable Types Library (PTypes) 参考网站:http://www.melikyan.com/ptypes/ q是STL的比较简单的替代品,以及可移植的多线E和|络库?/p>
(6) LFC 参考网站:http://lfc.sourceforge.net/ 哦,q又是一个尝试提供一切的C++?/p>
5.12 其他?/p>
(1) Loki 参考网站:http://www.moderncppdesign.com/ 哦,你可能抱怨我早该和Boost一起介l它Q一个实验性质的库。作者在loki?br />把C++模板的功能发挥到了极致。ƈ且尝试把cM设计模式q样思想层面的东襉K过 (2) ATL ATL(Active Template Library) 是一l小巧、高效、灵zȝc,q些cMؓ创徏可互操作的COMlg提供了基本的 (3) FC++: The Functional C++ Library q个库提供了一些函数式语言中才有的要素。属于用库来扩充语言的一个代?br />作。如果想要在OOP之外L另一分的乐趣Q可以去看看函数式程序设计的世界。大 (4) FACT! 参考网站:http://www.kfa-juelich.de/zam/FACT/start/index.html 另外一个实现函数式语言Ҏ的?/p>
(5) Crypto++ 提供处理密码Q消息验证,单向hashQ公匙加密系l等功能的免费库?/p>
q有很多非常Ȁ动h心或者是极其实用的C++库,限于我们的水q以及文章的?br />q不能包括进来。在对于q些已经包含q来的库的介l中Q由于ƈ不是每一个我?br />都用过Q所以难免有偏颇之处Q请读者见谅?/p>
------------------------------------------------------------------------ 6Q书c?/p>
以前熊节先生曾撰文评论相对于JavaE序设计语言QC++的好书多如牛毛。荣耀 http://www.royaloo.com/articles/articles_2003/9CppBooks.htm 下面几本书对于走在C++初学之\上的读者是我们最愿意推荐l大家的Q?/p>
(1) 《C++ Primer?/p>
哦,也许你会抱怨我们ؓ什么不先介lTCPL,但对于走在学习之路上的入门者, (2) 《Essential C++?/p>
如果说《C++ Primer》是C++领域的超U宝典,那么此书作ؓ掌握C++的大局?br />当之无愧。正如?NET大局观》一书能够让读者全?NETQ本书讲qCC++中最核心 (3) 《The C++ Programming Language?/p>
BjarneZ带来的C++教程Q真正能够告诉你怎么用才叫真正的C++的唯一一?br />书。虽然如同“某某程序设计语a”这L书籍会给大家一个内容全揽,入门到精 (4) 《Effective C++》,《More Effective C++?/p>
是的Q正如一些C++爱好者经总读过与没有读q上qC本作品来区分你是否是 技术书c仁者见仁,q多的评论反无太多意义,p者喜好选择最适合自己?br />书方Z{?/p>
------------------------------------------------------------------------ 7Q资源网?/p>
正如我们可以通过计算机历史上的重要h物了解计机史的发展QC++相关人物 (2) Stanley B. Lippman (3) Scott Meyers (4) David Musser (5) Bruce Eckel (6) Nicolai M. Josuttis (7) Herb Sutter (8) Andrei Alexandrescu (9) 侯捷先生 (10) 孟岩先生 (11) 荣耀先生 (12) 潘爱民先?br /> http://www.icst.pku.edu.cn/panaimin/pam_homepage.htm 除了上述大师的主外Q以下的l合cC++学习参考站Ҏ我们非常愿意向大?br />推荐的: (1) CodeProject (2) CodeGuru (3) Dr. Dobb's Journal (4) C/C++ Users Journal (5) Cl视?br /> http://www.c-view.org (6) allaboutprogram (1) ISO IEC JTC1/SC22/WG21 - C++Q标准C++的权威参?br /> http://anubis.dkuug.dk/jtc1/sc22/wg21/ (2) C++ FAQ LITE ?Frequently Asked Questions: 最为全面的C++FAQ (1) .alt.comp.lang.learn.c-c++ (2) .comp.lang.c++.moderated (3) .comp.std.c++ ------------------------------------------------------------------------ 8Q不得不写的l束?/p>
l束的时候也是ȝ现状Q展望未来的时候。虽然C++从脱胎于C开始,一路艰 C++在面向企业的软g开发中Q在开发便h等斚w的确要比Java和C#差很多, 从C++目前的活跃程度,以及应用现状来说是完全能够肯定C++仍然是Y件工?br />的基Q也不会退出历史舞台的。另外从BoostQLokiq些库中我们也能够看到C++ 需要看到的是两个趋势,一个趋势是C++变得更加复杂Q更加学院派Q通过模板
(T) expression // cast expression to be of type T
二?C++的四U强制{型Ş式:
C++ 同时提供了四U新的强制{型Ş式(通常UCؓ新风格的?C++ 风格的强制{型)Q?
每一U适用于特定的目的Q?
·dynamic_cast 主要用于执行“安全的向下转型Qsafe downcastingQ”,也就是说Q要定一个对象是否是一个承体pM的一个特定类型。它是唯一不能用旧风格语法执行的强制{型,也是唯一可能有重大运行时代h的强制{型?br />
·reinterpret_cast 是特意用于底层的强制转型Q导致实C赖(implementation-dependentQ(是_不可ULQ的l果Q例如,一个指针{型ؓ一个整数。这L强制转型在底层代码以外应该极为罕见?br />
==
class B { ... };
void f(B* pb)
If
pb really points to an object of type D, then pd1 and pd2 will get the
same value. They will also get the same value if pb == 0.
If pb
points to an object of type B and not to the complete D class, then
dynamic_cast will know enough to return zero. However, static_cast
relies on the programmer’s assertion that pb points to an object of
type D and simply returns a pointer to that supposed D object.
即dynamic_cast可用于承体pM的向下{型,卛_基类指针转换为派生类指针Q比static_cast更严格更安全?
dynamic_cast在执行效率上比static_cast要差一?但static_cast在更宽上范围内可以完成映?q种不加限制的映伴?
着不安全?static_cast覆盖的变换类型除cdơ的静态导航以?q包括无映射变换,H化变换(q种变换会导致对象切?丢失信息),?
VOID*的强制变?隐式cd变换{?..
reinterpret_cast是ؓ了映到一个完全不同类型的意?q个关键词在我们需要把cd映射回原有类型时用到?我们映射到的cd仅仅是ؓ了故弄玄虚和其他目的,q是所有映中最危险?(q句话是C++~程思想中的原话)
static_cast ?reinterpret_cast 操作W修改了操作数类? 它们不是互逆的; static_cast
在编译时使用cd信息执行转换, 在{换执行必要的?诸如指针界计算, cd?. 其操作数相对是安全的. 另一斚w,
reinterpret_cast 仅仅是重新解释了l出的对象的比特模型而没有进行二q制转换, 例子如下:
int n=9; double d=static_cast < double > (n);
上面的例子中, 我们一个变量从 int 转换?double. q些cd的二q制表达式是不同? 要将整数 9 转换?双精度整?9,
static_cast 需要正地为双_ֺ整数 d 补比特? 其结果ؓ 9.0. 而reinterpret_cast 的行为却不同:
int n=9;
q次, l果有所不同. 在进行计以? d 包含无用? q是因ؓ reinterpret_cast 仅仅是复?n 的比特位?d, 没有q行必要的分?
来源Qhttp://www.yuanma.org/data/2006/0723/article_1213.htm一.什么是字节寚w,Z么要寚w?
?字节寚w对程序的影响:
讄构体如下定义Q?br />struct A
{
int a;
char b;
short c;
};
struct B
{
char b;
int a;
short c;
};
现在已知32位机器上各种数据cd的长度如?
char:1(有符hW号?
short:2(有符hW号?
int:4(有符hW号?
long:4(有符hW号?
float:4 double:8
那么上面两个l构大小如何?
l果?
sizeof(strcut A)gؓ8
sizeof(struct B)的值却?2
#pragma pack (2) /*指定?字节寚w*/
struct C
{
char b;
int a;
short c;
};
#pragma pack () /*取消指定寚wQ恢复缺省对?/
sizeof(struct C)值是8?br />修改寚wgؓ1Q?br />#pragma pack (1) /*指定?字节寚w*/
struct D
{
char b;
int a;
short c;
};
#pragma pack () /*取消指定寚wQ恢复缺省对?/
sizeof(struct D)gؓ7?br />后面我们再讲?pragma pack()的作??~译器是按照什么样的原则进行对齐的?
对于char型数据,其自w对齐gؓ1Q对于short型ؓ2Q对于int,float,doublecdQ其自n寚wgؓ4Q单位字节?br />2.l构体或者类的自w对齐|其成员中自n寚w值最大的那个倹{?br />3.指定寚w?/font>Q?pragma pack (value)时的指定寚w值value?br />4.数据成员、结构体和类的有效对齐|自n寚w值和指定寚wg的那个倹{?br />?
了这些|我们可以很方便的来讨论具体数据l构的成员和其自w的寚w方式。有效对齐值N是最l用来决定数据存攑֜址方式的|最重要。有效对齐NQ就?
表示“对齐在N上”,也就是说该数据的"存放起始地址%N=0".而数据结构中的数据变量都是按定义的先后顺序来排放的。第一个数据变量的起始地址是?
据结构的起始地址。结构体的成员变量要寚w排放Q结构体本n也要Ҏ自n的有效对齐值圆?是l构体成员变量占用总长度需要是对结构体有效寚w值的整数
倍,l合下面例子理解)。这样就不能理解上面的几个例子的g?br />例子分析Q?br />分析例子BQ?br />struct B
{
char b;
int a;
short c;
};
?
设B从地址I间0x0000开始排放。该例子中没有定义指定对齐|在笔者环境下Q该值默认ؓ4。第一个成员变量b的自w对齐值是1Q比指定或者默认指?
寚w?,所以其有效寚wgؓ1Q所以其存放地址0x0000W合0x0000%1=0.W二个成员变量aQ其自n寚wgؓ4Q所以有效对齐g?Q?
所以只能存攑֜起始地址?x0004?x0007q四个连l的字节I间中,复核0x0004%4=0,且紧靠第一个变量。第三个变量c,自n寚wgؓ
2Q所以有效对齐g?Q可以存攑֜0x0008?x0009q两个字节空间中Q符?x0008%2=0。所以从0x0000?x0009存放?
都是B内容。再看数据结构B的自w对齐gؓ其变量中最大对齐?q里是bQ所以就?Q所以结构体的有效对齐g?。根据结构体圆整的要求,
0x0009?x0000=10字节Q(10Q?Q%4Q?。所?x0000A?x000B也ؓl构体B所占用。故B?x0000?x000B
共有12个字?sizeof(struct B)=12;其实如果p一个就来说它已满_节对齐了,
因ؓ它的起始地址?,因此肯定是对齐的,之所以在后面补充2个字?是因为编译器Z实现l构数组的存取效?试想如果我们定义了一个结构B的数l??
么第一个结构v始地址?没有问题,但是W二个结构呢?按照数组的定?数组中所有元素都是紧挨着?如果我们不把l构的大补充ؓ4的整数?那么下一
个结构的起始地址是0x0000A,q显然不能满结构的地址寚w?因此我们要把l构补充成有效对齐大的整数?其实诸如:对于char型数据,?
自n寚wgؓ1Q对于short型ؓ2Q对于int,float,doublecdQ其自n寚wgؓ4Q这些已有类型的自n寚wg是基于数l考虑??
是因些类型的长度已知?所以他们的自n寚wg已知了.
同理,分析上面例子CQ?br />#pragma pack (2) /*指定?字节寚w*/
struct C
{
char b;
int a;
short c;
};
#pragma pack () /*取消指定寚wQ恢复缺省对?/
W?
一个变量b的自w对齐gؓ1Q指定对齐gؓ2Q所以,其有效对齐gؓ1Q假设C?x0000开始,那么b存放?x0000Q符?x0000%1=
0;W二个变量,自n寚wgؓ4Q指定对齐gؓ2Q所以有效对齐gؓ2Q所以顺序存攑֜0x0002?x0003?x0004?x0005四个q箋
字节中,W合0x0002%2=0。第三个变量c的自w对齐gؓ2Q所以有效对齐gؓ2Q顺序存?br />?x0006?x0007中,W合
0x0006%2=0。所以从0x0000?x00007共八字节存放的是C的变量。又C的自w对齐gؓ4Q所以C的有效对齐gؓ2。又8%2=0,C
只占?x0000?x0007的八个字节。所以sizeof(struct C)=8.?如何修改~译器的默认寚w?
?针对字节寚w,我们在编E中如何考虑?
如果在编E的时候要考虑节约I间的话,那么我们只需要假定结构的首地址?,然后各个变量按照上面的原则进行排列即?基本的原则就是把l构中的变量按照
cd大小从小到大声明,量减少中间的填补空?q有一U就是ؓ了以I间换取旉的效?我们昄的进行填补空间进行对?比如:有一U用空间换旉?
法是昑ּ的插入reserved成员Q?br /> struct A{
char a;
char reserved[3];//使用I间换时?br /> int b;
}
reserved成员Ҏ们的E序没有什么意?它只是v到填补空间以辑ֈ字节寚w的目?当然即不加q个成员通常~译器也会给我们自动填补寚w,我们自己加上它只是v到显式的提醒作用.?字节寚w可能带来的隐?
unsigned int i = 0x12345678;
unsigned char *p=NULL;
unsigned short *p1=NULL;
*p=0x00;
p1=(unsigned short *)(p+1);
*p1=0x0000;
最后两句代码,从奇数边界去讉Kunsignedshort型变量,昄不符合对齐的规定?br />在x86上,cM的操作只会媄响效率,但是在MIPS或者sparc上,可能是一个error,因ؓ它们要求必须字节寚w.?如何查找与字节对齐方面的问题:
3. 如果支持看设|了寚w与否,如果没有则看讉K旉要加某些Ҏ的修饰来标志其特D访问操作?/p>
from DUI0067D_ADS1_2_CompLib
1.__align(num)
q个用于修改最高别对象的字节边界。在汇编中用LDRD或者STRD?br /> p用到此命令__align(8)q行修饰限制。来保证数据对象是相应对齐?br /> q个修饰对象的命令最大是8个字节限?可以?字节的对象进?字节
寚w,但是不能?字节的对?字节寚w?br /> __align是存储类修改,他只修饰最高cd对象不能用于l构或者函数对象?br />
2.__packed
__packed是进行一字节寚w
1.不能对packed的对象进行对?br /> 2.所有对象的d讉K都进行非寚w讉K
3.float及包含float的结构联合及未用__packed的对象将不能字节寚w
4.__packed对局部整形变量无影响
5.强制由unpacked对象向packed对象转化是未定义,整Ş指针可以合法?br /> 义ؓpacked?br /> __packed int* p; //__packed int 则没有意?br /> 6.寚w或非寚wd讉K带来问题
__packed struct STRUCT_TEST
{
char a;
int b;
char c;
} ; //定义如下l构此时b的v始地址一定是不对齐的
//在栈中访问b可能有问?因ؓ栈上数据肯定是对齐访问[from CL]
//下面变量定义成全局静态不在栈?
static char* p;
static struct STRUCT_TEST a;
void Main()
{
__packed int* q; //此时定义成__packed来修饰当前q指向为非寚w的数据地址下面的访问则可以
q = (int*)(p+1);
*q = 0x87654321;
/*
得到赋值的汇编指o很清?br />ldr r5,0x20001590 ; = #0x12345678
[0xe1a00005] mov r0,r5
[0xeb0000b0] bl __rt_uwrite4 //在此处调用一个写4byte的操作函?
[0xe5c10000] strb r0,[r1,#0] //函数q行4ơstrb操作然后q回保证了数据正的讉K
[0xe1a02420] mov r2,r0,lsr #8
[0xe5c12001] strb r2,[r1,#1]
[0xe1a02820] mov r2,r0,lsr #16
[0xe5c12002] strb r2,[r1,#2]
[0xe1a02c20] mov r2,r0,lsr #24
[0xe5c12003] strb r2,[r1,#3]
[0xe1a0f00e] mov pc,r14
*/
如果q没有加__packed修饰则汇~出来指令是q样直接会导致奇地址处访问失?br />[0xe59f2018] ldr r2,0x20001594 ; = #0x87654321
[0xe5812000] str r2,[r1,#0]
*/
}
]]>
C++对象内存布局
写这个文章完全是因ؓ惌搞清?vc 怎么布局每个 c++ 对象,以及怎样完成指针的{换的q程.
先问一个问?两个不同cd的指针相互{换以?他们在数g是一L?比如:
int nValue = 10;
int *pInt = &nValue;
void *pVoid = pInt;
char *pChar = (char*)pInt;
q些指针的?不是说指针指向的内存的内?是一L? 如果你的回答?
yes,那如果是一个类的承体pd?在承类向基c{换的q程?指针的数D是不变化的么?如果你的回答?不一定会变化,要看cȝ体系是怎么设计?
"的话,那恭喜你,不用看下M.如果你还不确定究竟变q是不变,I竟哪些?哪些不变,I竟Z么要变ؓ什么不变的?接着看下?
c++ 标准不规?c++ 实现的时候的对象的具体的内存布局,除了在某些方面有的限制以外,c++
对象在内存里面的布局完全是由~译器自行决?q里我也只是讨论 vc++ .net 2003 build 7.1.3091
的实现方?我ƈ没有?vc5 vc6 vc.net 2002 以及其他?2003 build
上面做过试,l论也许不适合那些~译q_.q些属于~译器具体实?ms 保留有在不通知你我的情况下作出更改的权?废话q么?马上开?
对于 c 的内建指针的转换,l果是不用多讨论?我们只是讨论 c++ 的对?从最单的开?
class CBase
{
public:
int m_nBaseValue;
};
q样的一个类在内存里攄是非常简单的,他占??bytes 的空?不用多说,我们从他z一个类出来.
class CDerive1 : public CBase
{
public:
int m_nDerive1Value;
};
CDerive1 的对象在内存里面是怎么攄? 也很?占有8?bytes 的空???bytes 属于 CBase c?后四?
bytes 属于自己.一个CDerive1 的指针{换成一?CBase 的指?l果是一L.下面我们加上多重l承看看.
class CFinal : public CDerive,public CBase // q里?CDerive 是一个和 CBase 差不多的基类
{
public:
int m_nFinalValue;
};
CFinal 的对象在内存里面的布局E微复杂一?但是也很Ҏ惌,他占?12 ?bytes 的空??个属?
CDerive,中间4个属?CBase,后面4个才是自q.那一?CFinal 的指针{换成一?CDerive 指针,数g变么?
转换成一?CBase 指针?又会变化?{案?前一个不?后一个要变化,道理非常的明?CFinal 对象的开头刚好是一?
CDerive 对象,?CBase 对象却在 CFinal 对象的中?自然是要变化的了,具体怎么变化? ?4 ?
ok(自然要检查是否是I指?.
CBase *pBase = pFinal ? (CBase*)((char*)pFinal + sizeof(CDerive)) : 0;// 当你写下 pBase = pFinal 的时?其实是这L
q种不带 virtual 的承就q么?只是加上一?offset 而已.下面我们看看如果加上 virtual function 的时候是什么样子的?
q是从简单类开?
class CBase
{
public:
virtual void VirtualBaseFunction(){}
int m_nBaseValue;
};
q里L没有使用 virtual destructor,因ؓq个函数E微有些不同.q是同样的问?CBase cd内存上占多大的空?q是
4 bytes ? {案?no, 在我的编译器上面?8 bytes,多出来的 4 bytes ?__vfptr(watch
H口看见的名?,他是一个指?指向了类?vtable,那什么是 vtable ?他是用来q什么的? vtable 是用来支?
virtual function
机制?他其实是一个函数指针数l?q不{同于c/c++语言里面的指针数l?因ؓ他们的类型ƈ不一定是一L.)他的每一个元素都指向了一个你定义?
virtual
function,q样通过一个中间层来到辑֊态连~的效果,q些指针是在E序q行的时候准备妥当的,而不是在~译的时候准备妥当的,q个是动态联~的
目的,具体是由谁来讄q些指针的呢?constructor/destructor/copy constructor/assignment
operator他们完成?不用奇?~译器会在你写的q些函数里面安插些必要的代码用来讄 vtable
的?如果你没有写q些函数,~译器会在适当的时候帮你生成这些函?明白一? vtable 是用来支?virtual function
机制?而需?virtual 机制的类基本上都会由一?__vfptr 指向他自q vtable.在调?virtual
function的时?~译器这样完?
pBase->VirtualBaseFunction(); => pBase->__vfptr[0]();// 0 是你的virtual function ?vtable 中的 slot number,~译器决?/font>
现在应该很想?CBase 的大了?那这?__vfptr 是放C么位|的? ?m_nBaseValue 之前q是之后?
在我的编译器上看?是在之前,Z么要攑ֈ之前,是因为在通过 指向cL员函数的指针调用 virtual function
的时候能些代码(指汇~代?,q个原因q里׃深入讨论?有兴的同学可以看看 inside the c++ object model 一?
接下?我们加上l承来看?
class CDerive1 : public CBase
{
public:
virtual void VirtualDerive1Function();
};
q个时候你也许要说,内存布局跟没?virtual 是一L,只不q每个类多了一?__vfptr
而已,?..q个是不对的,在我的编译器上面 两个cd享同一?__vfptr, vtable
里面放有两个指针,一个是两个cd享的,一个只属于 CDerive1 c?调用的时候如何呢?
pDerive1->VirtualDerive1Function() => pDerive1->__vfptr[1]();
pDerive1->VirtualBaseFunction() => pDerive1->__vfptr[0]();
至于指针的相互{?数D是没有变化的(也正是追求这U效?所以把 __vfptr 攑ֈcȝ开?因ؓ调整 this 指针也是要占有运行时的时间的).
现在加上多重l承瞧瞧,代码我不写上来了,p上面?CFinal, CDerive, CBase
体系一?只是每个cd一个VirtualxxxFunction出来,q个时候的指针调整q是没有什么变?所以我们只是看?vtable
的情?你会?CDerive ?CFinal ׃n一?__vfptr,?CBase 有一个自q __vfptr,?CFinal ?
__vfptr ?2 个slot,q个l论是正的. 同时你也会说 通过 CFinal c调?CBase 的函数是要进行指针调整的,yes
you'r right,不仅仅是 this 指针调整(?this 指针会成?function 的一个参?,q要调整 vtable 的?
pFinal->VirtualBaseFunction() => (CBase*)((char*)pFinal + sizeof(CDerive))->__vfptr[0]();
转换?asm 的代码大U是q样?
mov eax,[pFinal] ; pFinal is a local object,pFinal will be epb - xx
add eax,8 ; 8 = sizeof(CDerive)
mov ecx,eax ; ecx is this pointer
mov edx,[eax] ; edx = vtable address
call [edx] ; call vtable[0]
写到q里也就明白this指针是怎么调整??virtual function 的承也不复?this指针调整也是很简单的,下面看最复杂的部?virtual inheritance.
我的~译器支持虚拟承的方式和虚函数的方式差不多,都是通过一?table 完成,只是q个q不到 vc 赋予的名字了,我们叫他
vbtable ?~译器同样在c里面加入一个指?vbtable 的指?我们叫他 __vbptr ?q个指针指向?vbtable ,?
vbtable 里面的每一对应了一个基c?vbtable
记录了每个基cȝ某一个偏U量,通过q个偏移量就能计出具体cȝ指针的位|?看个单的例子:
class CBase
{
public:
virtual ~CBase(){}
};
class CMid1 : public virtual CBase
{
public:
virtual ~CMid1(){}
int m_nMid1;
};
class CMid2 : public virtual CBase
{
public:
virtual ~CMid2(){}
int m_nMid2;
};
class CFinal : public CMid1,public CMid2
{
public:
virtual ~CFinal(){}
int m_nFinal;
};
CFinal final;
CFinal *pFinal = &final; // pFinal = 0x0012feb4;
CBase *pBase = pFinal; // pBase = 0x0012fec8 = pFinal + 0x14;
CMid1 *pMid1 = pFinal; // pMid1 = 0x0012feb4 = pFinal;
CMid2 *pMid2 = pFinal; // pMid2 = 0x004210b4 = pFinal;
l果让你吃惊? 最奇怪的地方居然?CMid2 ?CMid1 的地址居然是一L,q个是因?vc ?vbtable 攑ֈ?
CFinal cȝ开头的原因,而CMid1 ?CMid2 也同栯使用q个 vbtable, 所?q个三个的地址也就必须相同??
CBase 的地址是怎么出来的呢? ?..刚刚我们说了 vbtable 攑ֈ了CFinal 的开?vc
一定会攑֜开头吗?{案是不一?q个E后解释).在我的机器上?final 对应内存的第一?dword ?
0x00426030,查看q个地址,W一个dword ?0 ,W二个就?0x14,刚好?pBase
的偏Uȝ?q个只是巧合,也许你换个类的承体pd完全不同?但是我只是想说明一?基类的偏U计是?vbtable
的值相兌?下面我们来看看 vc 是怎么计算q些偏移?
vc 在分析我们的代码的时?生成了一份类的承体pM?其中有一个叫 thisDisplacement 的_PMDl构:
struct _PMD // total undocumented
{
int mdisp; // i think the meaning is Multiinheritance DISPlacement
int pdisp; // Pointer to vbtable DISPlacement
int vdisp; // Vbtable DISPlacement
};
l构的名字和成员变量的名字确实实是 vc 的名??watch H口输入 (_PMD*)0
p看到q个l构的详l信?,每个字段的含义却是我自己猜测出来?mdisp 大概用来表示多重l承(包括单一l承)的时候的偏移?pdisp
表示 vbtable 的偏U量,?vdisp 表示cd vbtable
里面的下?那么有了q个l构怎样才能完成指针的{换呢?假如我们有一个派生类指针
pFinal,要{换成一个特定的基础c?我们首先要知道和q个基类对应?_PMD
l构的信?q个信息的获?我暂时没有找C个非常方便的Ҏ,现在我用的Ҏ下面会有描述),有了q个信息以后,转换方便了.首先扑ֈ
vbtabel 的地址 *(pFinal + pdisp),然后扑ֈ基类的偏U?*(*(pFinal + pdisp) + vdisp)
q个偏移值是相对vbtable?所以还要加?vbtable的偏U?最后加?mdisp的偏U?如下:
char *pFinal = xxx; // need a init value
char *pBase; // we must calc
pBase = pFinal + mdisp + *(int *)(*(int *)(pFinal + pdisp) + vdisp) + pdisp;
注意: ?pdisp < 0 的时候就表示q个cL?vbtable 直接使用 pFinal + mdisp 得到结果了.
所以这个结构是一个通用的结?专门用作cd转换,不管是有无虚l承都能使用q个l构q行cd转换.
通过q个l构,我们也能看到 vc 是怎样布局q个 object ?
看到q里,也许你要大呼一口气,妈妈呀,一个类型{换要q么的麻烦吗?我直接写 pBase = pFinal 不就可以了吗? 恭喜你还没有被我忽悠得晕头{?哈哈.其实你写下那行语句的时?~译器在帮你做这个{?大约生成下面的代?br />
mov eax,[pFinal] ;final address
mov ecx,[eax] ; vbtable address *(int *)(pFinal + pdisp)
mov edx,eax ; save to edx
add edx,[ecx + 4] ; ecx + 4 is (*(int *)(pFinal + pdisp) + vdisp)
mov [pBase],edx ; edx = pFinal + mdisp + *(int *)(*(int *)(pFinal + pdisp) + vdisp) + pdisp;
; here mdisp = 0, pdisp = 0, vdisp = 4
也许你要说了,我要q些东西来干什?要{换的时候直接{换就好了,~译器会帮做,的确,大多数的时候确实是q样,但是,在某些时候却q不如此,现在?
要实C个功?输入一个指?输入一?_PMD l构,你要实现一个AdjustPointer
的函数来生成另一个指?q个时候你也只能这样完成了,因ؓ我没有给你两个指针的名字,ql了你字W串形式的名字也没有??...你也怼?办法
是有?的确是有,模板p实现q种功能,?.q个我们暂时不讨论具体的实现l节.也许你要问了,I竟什么时候会d现这U听都没有听q的功能,其实q?
个函数是真正存在?只不q不是由你来实现?而是 ms 的h实现?你只用写一?带有 c++ 异常的程?使用 ida
反汇~?然后查找函数,p扑ֈq个函数?他用来在异常处理时创?catch 所需要的
object.至于q个详细的信?h?我会最快速度写出关于 vc 是怎样实现 c++ 异常的文章来.
最后了,说说那个
_PMD l构的获取方?看的时候不要吃?Ҏ比较的麻?比如我想知道?CFinal cȝ关的 _PMD 信息,先新建工?写下
throw pFinal q样的语?~译,在这个语句的地方讄断点,q行,转到反汇~?q入 __CxxThrowException@8
函数,q个时候不出意外你能看C个叫 pThrowInfo 的东?如果看不?h开"昄W号?选项),?watch
H口里面输入pThrowInfo,展开?看到一个pCatchableTypeArray,记录下他?
nCacthableTypes的?然后?watch 里面输入
pThrowInfo->pCatchableTypeArray->arrayOfCatchableTypes[0]
?pThrowInfo->pCatchableTypeArray->arrayOfCatchableTypes[n], n
是你刚刚记录的值减1,再展开他们,你就能看C?thisDisplacement 的数?l箋展开是 mdisp
{等?很是ȝ??.你已l猜C,q个是和异常有关pȝ.
后记:
q段旉,我一直在M反汇~之后的代码,也颇有些心得,所以才有想法写一些文?探讨 vc
~译器鲜Zh?太过狂妄?的秘?q个斚w的文章也有h写过,那些文章也给我不的启发,我不认ؓ自己是第一个发现这些秘密的?但是臛_我自q?
?我是W一个把q些东西写出来的?文章里面作墨多的部分都是自己发现?p个文章里面的内容来说,inside the c++ object
model 是有比较详细的描?但是他ƈ不是转换针对 vc q个~译器的实现,?_PMD q个l构我也没有在什么地方见有h描述q?只是?
windows develop network
?002q?2月的杂志上看有h提到q这个结?可惜他却没有了解(臛_他在他发表文章的时候是如是说的)q个l构的用?正是因ؓq个原因,我才有写
q个文章以及后箋文章的冲?.所?q个文章也算是我自己的原创吧.q个文g虽然和游戏制造没有太大的关系,但是?T
自视清高,不愿意自q文章被一帮不懂的h评hȝ,所以也没有发到那些著名?xxx |站,只发 goldpoint.转蝲h明出??T 对自qW一个原创文章比较珍?比较重视,谢谢).
]]>
函数调用规范stdcall
cdecl
fastcall
thiscall
naked callstdcall调用规范
int __stdcall function(int a,int b)
1Q参C叛_左压入堆栈;
2Q函数自w修改堆栈;
3) 函数名自动加前导的下划线Q后面紧跟一个@W号Q其后紧跟着参数的尺寸?/font> push 2 W二个参数入?br /> push 1 W一个参数入?br /> call function 调用参数Q注意此时自动把cs:eip入栈
push ebp 保存ebp寄存器,该寄存器用来保存堆栈的栈顶指针Q可以在函数退出时恢复
mov ebp,esp 保存堆栈指针
mov eax,[ebp + 8H] 堆栈中ebp指向位置之前依次保存有ebp,cs:eip,a,b,ebp +8指向a
add eax,[ebp + 0CH] 堆栈中ebp + 12处保存了b
mov esp,ebp 恢复esp
pop ebp
ret 8 cdecl调用规范
int function (int a ,int b) // 不加修饰是C调用U定
int __cdecl function(int a,int b) // 明确指出C调用U定调用?br /> push 1
push 2
call function
add esp,8 注意Q这里调用者在恢复堆栈
被调用函数_function?br /> push ebp 保存ebp寄存器,该寄存器用来保存堆栈的栈顶指针Q可以在函数退出时恢复
mov ebp,esp 保存堆栈指针
mov eax,[ebp + 8H] 堆栈中ebp指向位置之前依次保存有ebp,cs:eip,a,b,ebp +8指向a
add eax,[ebp + 0CH] 堆栈中ebp + 12处保存了b
mov esp,ebp 恢复esp
pop ebp
ret 注意Q这里没有修改堆?/font>int sprintf(char* buffer,constchar* format,...)
fastcall调用规范
1) 函数的第一个和W二个DWORD参数Q或者尺寸更的Q通过ecx和edx传递,其他参数通过从右向左的顺序压栈;
2) 被调用函数清理堆栈;
3) 函数名修改规则同stdcall?/font> thiscall调用规范
1) 参数从右向左入栈Q?br /> 2) 如果参数个数定Qthis指针通过ecx传递给被调用者;如果参数个数不确定,this指针在所有参数压栈后被压入堆栈;
3) 对参CC定的Q调用者清理堆栈,否则函数自己清理堆栈?/font>
class A
{
public:
int function1(int a,int b);
int function2(int a,...);
};
int A::function1 (int a,int b)
{
return a+b;
}
int A::function2(int a,...)
{
va_list ap;
va_start(ap,a);
int i;
int result = 0;
for(i = 0 ; i < a ; i ++)
{
result += va_arg(ap,int);
}
return result;
}
void callee()
{
A a;
a.function1(1,2);
a.function2(3,1,2,3);
}// 函数function1调用
0401C1D push 2
00401C1F push 1
00401C21 lea ecx,[ebp-8]
00401C24 call function1 注意Q这里this没有被入?br /> // 函数function2调用
00401C29 push 3
00401C2B push 2
00401C2D push 1
00401C2F push 3
00401C31 lea eax,[ebp-8] q里引入this指针
00401C34 push eax
00401C35 call function2
00401C3A add esp,14h naked call调用规范
__declspec(naked) int add(int a,int b)
{
__asm mov eax,a
__asm add eax,b
__asm ret
} mov eax,[ebp+8]
add eax,[ebp+12]
ret 8 __declspec(naked) int __stdcall function(int a,int b)
{
__asm mov eax,a
__asm add eax,b
__asm ret 8//注意后面?
} 函数调用U定D的常见问?/font>
1) 函数原型声明和函C定义不一?br /> 2) DLL导入函数时声明了不同的函数约?/font>
]]>
C++资源之不完全导引Q完整版Q?/font>
所有?/p>
--------
学不会”的无奈。Stan Lippman先生曑֜《C++ Primer》一书中指出“C++是最为难
学的高E序设计语言之一”,Z常将“之一”去掉以表达自己对C++的敬畏。诚
ӞC++E序设计语言对于学习者的有很多难以逾越的`沟,体系l构的庞大,?br />接不暇ƈ不断扩充的特性……除此之外,参考资料之多与冗杂使它的学习者望而却
步,Ʋ求深入者苦不堪a。希望这一份不完全导引能够成ؓ您C++学习之\上的引\
灯?/p>
史与其前期发展中诸多技术的演变Q你应当d考Bjarne的《The Design and Evo
lution of C++》。当然也不打给大家一个无所不包的宝典(q不想Q其一是因
水^有限Q其二无奈C++之博大精深)Q所l出的仅仅是一些我们认为对于想学习C
++的广大读者来说最重要q且触手可及的开发与学习资源?/p>
所裨益?/p>
--------
门相当复杂的语言Q所以编译器也难于构建。直到最q我们才开始能够用上完全
W合C++标准的编译器Q哦Q你可能会责怪那些编译器厂商不能早的提供符合标?br />的编译器Q这只能怪他们各自维pȝ自n的一套别Z愿接受的标准Q。什么??br />说这无关紧要Q哦Q不Q你所需要的是和标准化C++高度兼容的编译环境。长q来?br />Q只有这L~译器对C++开发h员来说才是最有意义的工具Q尤其是对于E序设计
语言的学习者。一x让代码具备可移植性,q让一门语a及其库的应用更ؓq泛
。嗯Q是的,我们q里只打介l一些公认的优秀~译器?/p>
~译器。(哦,我之所以将之分ZU开发环境你应当能明白ؓ什么,正如Delphi
7到Delphi8的{变,是革命性的两代。)Borland C++p牌开发工具厂商Borland
們֊打造。该公司的编译器素以速度快,I间效率高著UͼBorland C++ pd~译
器秉承了q个传统Q属于非怼质的~译器。标准化斚w早在5.5版本的编译器中对
标准化C++的兼容就辑ֈ?2.73%。目前最新版本是Borland C++ Builder X中的6.
0版本Q官方称100%W合ANSI/ISO的C++标准以及C99标准。嗯…这正是我前面所指的
“完全符合C++标准的编译器”?/p>
005 Whidbey中带的C++~译器。由Microsoft公司研制。在Visual Studio 6.0中,
因ؓ~译器有太多地方不能与后来出现的C++标准相吻合而饱受批评(x你在使用
STL的时候编译时报出的那些o人厌恶的error和warning吧)。VC++6.0Ҏ准化C+
+的兼容只?3.43%。但是随着C++~译器设计大师Stanley Lippman以及诸多C++C?br />达人的加盟Q在Visual Studio.NET 2003中,Visual C++~译器已l成Z个非
常成熟可靠的C++~译器了。Dr.Dobb's Journal的评显CVisual C++7.1Ҏ准C
++的兼Ҏ高?8.22%Q一度成为CBX之前兼容性最好的~译器。结合强大的Visua
l Studio.NET开发环境,是一个非怸错的选择。至于Whidbey时代的Visual C++,
g微Y所最x的是C++/CLI……我们不惌论微软下一代的C++~译器对标准?br />兼容如何Q但他确实越来越适合.NET (其实你和我的感觉可能是一LQ微软不?br />当把标准C++q块肥肉丢给Borland,然而微软可能ƈ不这栯??/p>
常好的移植性,你可以在非常q泛的^C使用它,同时也是~写跨^収ͼ嵌入?br />E序很好的选择。另外在W合标准q个斚w一直都非常好,GCC3.3大概能够辑ֈ96
.15%。但是由于其跨^台的Ҏ,在代码尺寔R度{优化上略微差一炏V?/p>
--------
境,q没有包括一些小型的Q罕见的IDE。其中Q何一N是功能丰富,可以用作?br />常开发用的。对于不同层面的开发者,请参见内文关于适用对象的描q?/p>
Studio.NET的庞大nw,以及初学者ƈ不那么高的功能要求,所以推荐这个开发环
境给C++的初学者,供其学习C++的最基本的部分,比如C的那部分子集Q当然你别指
望他能够支持最新的C99标准。在日常的开发中Q仍然有很多公司使用q个l典E_
的环境,比如W者就看曾亲见有些公司其~译器替换ؓGCC做手机开发之用?/p>
功能。结合其最新的C++~译器。对于机器配|比较好的开发h员来_使用q个开
发环境将能满_大部分的要求。这里不打算单独说Visual Studio Whidbey,虽然
Visual Studio .NET 2005 - WhidbeyC预览版已l推出,但暂不是很稳定,读?br />可以亲nM验?/p>
写的IDEQ速度比较快。它有一个很完善的GUIH体设计器,和Delphiq一个VCL?br />׃q些特点Q比较适合初学者上手。但是由于其GUI的中心位|,可能不利于对?br />C++语言的学习。而且其ؓ了支持VCLq个Object Pascal写的库也对C++q行了一?br />U有的扩充。得h们有一个不得不接受的事实:“Borland C++ Builder 6的高?br />几乎都是Delphi高手”?/p>
境,C++BuilderX则是完全从C++的角度思考得出的一个功能丰富的IDE。其最大的?br />Ҏ跨^収ͼ跨编译器Q多UFramework的集成,q且有一个WxWindows为基的GU
I设计器。尤其是采用了纯C++来重写了整个Framework,摒弃了以前o人无奈的版本
。对于C++的开发来_从编译器Q到库,到功能集成都是非常理想的。可以预见,
Borland C++ Builder X 2.0很值得C++爱好者期待。唯一令h隑֠之处是作Z?br />C++的开发工P其IDE是用Java写的Q在配置不够理想的机器上h重考虑再安?br />?/p>
序,你的水^应该_指导我们来写q篇陋文了?/p>
时候,GCC是一个让Windows下开发者流口水的编译器。Dev-C++是能够让GCC?br />在Windows下的工具Q作为集成开发环境,q提供了同专业IDE相媲的语法高亮Q?br />代码提示Q调试等功能。由于用Delphi开发,占用内存,速度很快Q比较适合
轻量U的学习和用?/p>
的神物。说其神奇是因ؓQ它本n是用Java写的Q但是拥有比一般Java写的E序?br />得多的速度。而且因ؓ其基于插件组装一切的原则Q得能够有CDTq样的插件把E
clipse变成一个C/C++的开发环境。如果你一直用Eclipse写Java的程序,不妨用它
体验一下C++开发的乐趣?/p>
--------
或者组件生准的文档。Doc-O-Matic使用源代码中的符号和注释以及外部的文?br />文g创徏与流行的文档样式一致的文档?/p>
中的cdơ结构。DocVizor快速地产生完整可供打印的类层次l构图,包括从第?br />方库中来的那些类Q除此之外DocVizorq能从类信息中生HTML文g?/p>
++代码的重构能够尽可能的有效率和简单?/p>
提出警告信息?/p>
C++的类?/p>
是再ơ编译?/p>
d了对multimethod的支持?/p>
数参数。它是一个编译器的外壟?/p>
U的开源测试框架。CppUnit ?JUnit 一样主要思想来源于极限编E。主要功能就
是对单元试q行理Qƈ可进行自动化试?/p>
(3) Cantata++
展单元测试和集成试的需?
yplus/index.shtml
o内自动化调试q程加速开发ƈ且羃短上市的周期。BoundsChecker提供清楚Q详l?br />的程序错误分析,许多是对C++独有的ƈ且在staticQstack和heap内存中检和?br />断错误,以及发现内存和资源的泄漏。 (6) Insure++
发者提供完整的错误诊断Q和q行时性能分析工具包?/p>
误?/p>
--------
Q直到标准的出台才正式定型,但是在标准库的实C却很令hƣ慰得看到多U实
玎ͼq且已被实践证明为有工业U别强度的佳作?/p>
其OEM的licenseQ在其C/C++的品中采用Dinkumware的库?/p>
Ҏ准C++的强调,是编写^台无养ICC++的开发者必备的工具。但是Boost中也
有很多是实验性质的东西,在实际的开发中实用需要}慎。ƈ且很多Boost中的库功
能堪U对语言功能的扩展,其构造用精巧的手法Q不要N然的p旉研读。Bo
ost另外一面,比如Graphq样的库则是h工业强度Q结构良好,非常值得研读?br />_֓代码Qƈ且也可以攑ֿ的在产品代码中多多利用?/p>
发中QGUI库的选择也是非常重要的一件事情,下面我们lD一下可选择的GUI库,
各自的特点以及相兛_L支持?/p>
ws API 之上Q能够ɽE序员的工作更容?~程效率高,减少了大量在建立 Windo
ws E序时必ȝ写的代码Q同时它q提供了所有一?C++ ~程的优点,例如l承
和封装。MFC ~写的程序在各个版本的Windows操作pȝ上是可移植的Q例如,?br />Windows 3.1下编写的代码可以很容易地UL?Windows NT ?Windows 95 上。但
是在最q发展以及官Ҏ持上日渐势微?/p>
很容易扩展,q且允许真正地组件编E。自?996q早些时候,Qtq入商业领域Q?br />它已l成为全世界范围内数千种成功的应用程序的基础。Qt也是行的Linux桌面?br />境KDE 的基Q同时它q支持Windows、Macintosh、Unix/X11{多U^台?/p>
器就是基于这个库的?/p>
该是什么样子的感受出发Q从而开始了对这个库的开发。有兴趣的可以尝试一下?/p>
(5) WTL
寸,以及速度优化斚w做得非常C。主要面向的使用体是开发COM轻量U供|络
下蝲的可视化控g的开发者?/p>
Communication EnvironmentQ是可以自由使用、开放源代码的面向对象框Ӟ?br />其中实现了许多用于ƈ发通信软g的核心模式。ACE提供了一l丰富的可复用C++?br />装外观(Wrapper FacadeQ和框架lgQ可跨越多种q_完成通用的通信软gd
Q其中包括:事g多\分离和事件处理器分派、信号处理、服务初始化、进E间?br />信、共享内存管理、消息\由、分布式服务动态(重)配置、ƈ发执行和同步Q等
{?/p>
tml
。XML验证在文档类型定?Document Type DefinitionQDTD)斚w有很好的支持Q?br />q且?001q?2月增加了支持W3C XML Schema 的基本完整的开放标准?/p>
生相应的GUIE序来修改这个parser。在DOM和SAX两大LXML解析办法之外提供?br />另外一个可行的解决Ҏ?/p>
rQ这个xpp把这层暴露出来直接给大家使用。在要充分考虑速度的时候值得试?/p>
(4) Xalan
OM和SAX之外L一点灵感?/p>
的数值程序,?Fortran?0%左右Q因此Blitz++正是要改掉这个缺炏V方法是?br />用C++的template技术,E序执行甚至可以比Fortran更快。Blitz++目前仍在发展?br />Q对于常见的SVDQFFTsQQMRES{常见的U性代数方法ƈ不提供,不过使用者可?br />很容易地利用Blitz++所提供的函数来构徏?/p>
象设计方便了快速的E序开发,对ƈ行机器进行了优化以达到最高的效率Q方便在
工业和研I环境中使用?/p>
矩阵的大量线性代数方面的功能。在某些应用使用高性能~译器的情况下,比如In
tel的编译器Q从产生的汇~代码可以看出其与手写几乎没有两L效能?/p>
部分重要的解x案和Ҏ以C++库的形式提供l工业和学术界的用户?/p>
B,以及S3MQ,控制接口Q键盘,鼠标和遥感)QXMS?/p>
先生Z国游戏开发事业所做出的A献?/p>
。它的目的是让开发者能更方便和直接地开发基?Dg讑֤的应用程序或游戏?br />引擎中的cdҎ底层的系l库Q如QDirect3D和OpenGLQ的全部使用l节q行?br />抽象Qƈ提供了基于现实世界对象的接口和其它类?/p>
中很隄到的大量的线E方面的功能?/p>
代码Qƈ且支持多U程环境和UnicodeQ同时还有正则表辑ּ的支持?/p>
机制Qi/opȝ包括Z插g的网l协议透明的i/o架构Q基于插件的应用E序消息
日志框架Q访问sql数据库的cȝ{?/p>
U程QUnicodeQ废料收集,I/OQ网l,实用工具QXMLQ等{)Q以及对Java, P
erl, Python, TCL, Lisp, COM ?CORBA的集成?/p>
库来提供。同时还提供了智能指针这h较实用的功能?/p>
设施?/p>
师Peter Norvig?“Teach Yourself Programming in Ten Years”一文中将?br />数式语言列ؓ臛_应当学习?cȝE语a之一?/p>
--------
先生在《程序员》杂志上撰文《C++E序设计之四书五l》也本领域内几乎所有的
l典书籍作了全面的介l?M关于书的评论此时看来便是很多余的了。个人浅见,
除非你打以C++作ؓ唯一兴趣或者生存之本,一般读者确实没有够的旉和必?br />?0余本书籍全部阅读。更有参考h值的是荣耀先生的另一文章:《至应该阅
ȝ九本C++著作》,可以从下面的地址览到此文:
本书内容更ؓ全面Q更l易懂,我们U它为“C++的超U宝典”ƈ不过分。配?br />一本不错的习题解答《C++ Primer Answer Book》可以辅助你的学习之路?/p>
的全部主题。书虽不厚,内容_Q不׃ؓ《C++ Primer》读者茶余饭后的主题?br />之作?/p>
通的感觉Q但本书实不太适合初学者阅诅R如果你自认为是一名很有经验的C++E?br />序员Q那臛_也要反复咀嚼Bjarne先生所的若q内宏V?/p>
C++高手。我们也极力推崇q两本著作。在各种介绍C++专家l验的书c里面,q两
本是最贴近语言本质Q看后最能够有脱胎换骨感觉的书,L书你需每日三省汝n
?/p>
--------
的网站也可以使我们得到最有h值的参考与借鉴Q下面的人物我们认ؓ没有介绍?br />必要Q只因下面的人物在C++领域的地位众所周知Q我们只相关的资源q行|列?br />供读者学习,他们有的工作于贝实验室Q有的工作于知名~译器厂商,有的在不
断推q语a的标准化Q有的ؓ读者撰写了多部千古奇作…?br /> (1) Bjarne Stroustrup
http://www.research.att.com/~bs/
http://blogs.msdn.com/slippman/
中文?http://www.zengyihome.net/slippman/index.htm
http://www.aristeia.com/
http://www.cs.rpi.edu/~musser/
http://www.bruceeckel.com
http://www.josuttis.com/
http://www.gotw.ca/
http://www.coderncppdesign.com/
http://www.jjhou.com
先生J忙于工作,痴迷于技术,暂无个h主页Q关于先生的作品可以通过CSDN
的专栏和侯先生的主页讉K到?/p>
http://www.royaloo.com/
http://www.codeproject.com
http://www.codeguru.com
http://www.ddj.com
http://www.cuj.com
http://www.allaboutprogram.com
其他资料
http://www.sunistudio.com/cppfaq/index.html
C/C++ 新闻l:
你不妨尝试从q里提问和回{问题,很多不错的Q&A资源......
q个单些Q如果你和我一h个菜?/p>
嗯,q个昄水^高一?/p>
如果你需要讨论标准C++相关话题的话
--------
隑֝L走过来,但是无论如何C++已经取得了工业基的地位。文章列丄大量相关
资源是最好的证明Q而业界的大量用C++写成的品代码以及大量的C++职业工程
师则是最直接的证明。同Ӟ我们可以看到各个高校的计机专业都开设有C++q门
评Q网l上对于C++的学习讨Z从来都没有停q。但是,在Java?NET两大企业
开发^台的围攻下,lh的感觉是C++来“不行”了?/p>
其中一个问题是C++语言本n比较复杂Q学习曲U比较陡峭,另外一个问题是C++?br />准化的时间太长,丧失了很多的壮大ZQ耗费了很多精力在厂商的之间的斗争?br />Q而C++的标准库M个完善的E序开发框架还~少太多太多的内容,各个W三方的
cd和框架又在一致性和完整性上没法和随q_提供的框架相提ƈ论。难道C++真的
要退出历史舞CQ?/p>
的发展非常活跃,对于新技术新思维非常Ȁq,C++仍然q泛受到x。从ACE在高
性能通信领域的应用,以及MTLq样的库在数D领域的表现Q我们可以看?br />C++在高性能应用场合下的不可替代的作用,而嵌入式pȝq样的内存受限开发^?br />Q比如Symbian OS上,C++已经发挥着q且发挥更大的作用。可以预见的是以后的
软g无论上层的应用怎么变,它的底层核心都会是由C/C++q样的系l软g~写?br />Q比如Java虚拟机,.NET Framwork。因为只有这LpȝUY件才能完全彻底的?br />挥机器的功能?/p>
{有潜力的语法因素构造越来越_y的库成ؓ了现代C++的热点,虽然在利用库实现
新的~程范式Q乃臌计模式等斚w很有开创意义,也确实生了一些能够便捷开
发的工具Q但是更多的是把C++变得更加强大Q更加复杂,也更加难懂,g也更?br />学院z,不得不说它正在向边缘化道路发展。另一个趋势是C++在主的企业应用开
发中已经逐渐退ZQERPq样的企业Y件开发中基本上不会考虑C++Q除非需要?br />虑性能或者和遗留代码的集成这些因素。C++退守到pȝU别语言Q成Y件工业的
基础是大势所。然而反思一下,真的是退守么Q自从STL出现Q无数的人风起云?br />的开始支持C++,他们狂呼“我看到深夜消失了,目标软g工程的出现。我看到了可
l护的代码。”是的,STL在可l护性下做得如此。但是又怎样呢?STL为C++?br />q了C软g工程的道路,而在上层应用E序软g开发领域这块场地早不单独属?br />C++,很多E序设计语言都做得很Q疯狂的支持者会毫不犹U地说我们应当支持
C++,因ؓ它是世界上最的语言。而坦率地_你的腰杆真的那么么Q也许只?br />在逃避一些事实。C++是优U的,q不可否认,STL的出现让C++一度走上了最辉煌?br />时刻Q然而现在看来……我的一位恩师曾aQ真正能够将STL应用得淋漓尽致的人很
保守地说国内也不过200人,或许不加入STL能够使C++向着它应当发展的方向发展
的更好,而现在看来,C++也应当回首到真正属于他的那一片圣C…?/p>
作者:
C++?U类型{?
一、C 风格QC-styleQ强制{型如下:
函数风格QFunction-styleQ强制{型用这L语法Q?br /> T(expression) // cast expression to be of type T
q两UŞ式之间没有本质上的不同,它纯_就是一个把括号攑֜哪的问题。我把这两种形式UCؓ旧风|old-styleQ的强制转型?
const_cast(expression)
dynamic_cast(expression)
reinterpret_cast(expression)
static_cast(expression)
·static_cast 可以被用于强刉型{换(例如Qnon-const 对象转型?const 对象Qint 转型?
doubleQ等{)Q它q可以用于很多这L转换的反向{换(例如Qvoid*
指针转型为有cd指针Q基cL针{型ؓzcL针)Q但是它不能一?const 对象转型?non-const 对象Q只?
const_cast 能做刎ͼQ它最接近于C-style的{换?br />
·const_cast 一般用于强制消除对象的帔R性。它是唯一能做到这一点的 C++ 风格的强制{型?
旧风格的强制转型依然合法Q但是新的Ş式更可取。首先,在代码中它们更容易识别(无论是hq是?grep
q样的工具都是如此)Q这样就化了在代码中Lcdpȝ被破坏的地方的过E。第二,更精地指定每一个强制{型的目的Q得编译器诊断使用错误成ؓ?
能。例如,如果你试图用一?const_cast 以外的新风格强制转型来消除常量性,你的代码无法编译?
== dynamic_cast .vs. static_cast
==
class D : public B { ... };
{
D* pd1 = dynamic_cast<D*>(pb);
D* pd2 = static_cast<D*>(pb);
}
==
== static_cast .vs. reinterpret_cast
==
double d=reinterpret_cast<double & > (n);
]]>
堆和栈的区别
一般认为在c中分几个存储?
1?- 有编译器自动分配释放
2?- 一般由E序员分配释放,若程序员不释放,E序l束时可能由OS回收
3全局区(静态区Q,全局变量和静态变量的存储是放在一块的Q初始化的全局变量和静
态变量在一块区域,未初始化的全局变量和未初始化的静态变量在盔R的另一块区域?
- E序l束释放
4另外q有一个专门放帔R的地斏V?- E序l束释放
在函C中定义的变量通常是在栈上Q用malloc, calloc, realloc{分配内存的函数?
配得到的是在堆上。在所有函C外定义的是全局量,加了static修饰W后不管在哪
里都存放在全局区(静态区Q?在所有函C外定义的static变量表示在该文g中有效,
不能extern到别的文件用Q在函数体内定义的static表示只在该函C内有效。另外,
函数中的"adgfdf"q样的字W串存放在常量区?
比如Q?
int a = 0; 全局初始化区
char *p1; 全局未初始化?
main()
{
int b; ?
char s[] = "abc";?
char *p2; ?
char *p3 = "123456"; 123456\0在常量区Qp3在栈上?
static int c =0Q?全局Q静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得来?0?0字节的区域就在堆区?
strcpy(p1, "123456"); 123456\0攑֜帔R区,~译器可能会它与p3所指向?12345
6"优化成一块?
}
q有是函数调用时会在栈上有一pd的保留现场及传递参数的操作?
栈的I间大小有限定,vc的缺省是2M。栈不够用的情况一般是E序中分配了大量数组?
递归函数层次太深。有一点必ȝ道,当一个函数调用完q回后它会释放该函数中所?
的栈I间。栈是由~译器自动管理的Q不用你操心?
堆是动态分配内存的Qƈ且你可以分配使用很大的内存。但是用不好会生内存泄漏?
q且频繁地malloc和free会生内存碎片(有点cM盘片Q,因ؓc分配动态内存时
是寻扑配的内存的。而用栈则不会产生片?
在栈上存取数据比通过指针在堆上存取数据快些?
一般大家说的堆栈和栈是一LQ就是栈(stack)Q而说堆时才是堆heap.
栈是先入后出的,一般是由高地址向低地址生长?
?heap)和栈(stack)是C/C++~程不可避免会碰到的两个基本概念?br />首先Q这两个概念都可以在讲数据结构的书中扑ֈQ他们都是基本的数据l构Q虽然栈更ؓ单一些。在具体的C/C++~程框架中,q两个概念ƈ不是q行的。对底层机器代码的研I可以揭C,栈是机器pȝ提供的数据结构,而堆则是C/C++函数库提供的?具体地说Q现代计机(串行执行机制)Q都直接在代码底层支持栈的数据结构。这体现在,有专门的寄存器指向栈所在的地址Q有专门的机器指令完成数据入栈出栈的操作?
q种机制的特Ҏ效率高,支持的数据有限,一般是整数Q指针,点数等pȝ直接?持的数据cdQƈ不直接支持其他的数据l构。因为栈的这U特点,Ҏ的用在E序中是非常频繁的。对子程序的调用是直接利用栈完成的。机器的call指o里隐含了把返回地址推入栈,然后跌{臛_E序地址的操作,而子E序中的ret指o则隐含从堆栈中弹回地址q蟩转之的操作。C/C++中的自动变量是直接利用栈的例子,q也是Z么当函数q回Ӟ该函数的自动变量自动失效的原?因ؓ 颜换指戳说饔们暗 状??
和栈不同Q堆的数据结构ƈ不是ql?无论是机器系l还是操作系l?支持的,而是由函数库提供的。基本的malloc/realloc/free函数l护了一套内部的堆数据结构。当E序使用q些函数去获得新的内存空间时Q这套函数首先试图从内部堆中L可用的内存空_如果没有可以使用的内存空_则试囑ֈ用系l调用来动态增加程序数据段的内存大,新分配得到的I间首先被组l进内部堆中去,然后再以适当的Ş式返回给调用者。当E序释放分配的内存空间时Q这片内存空间被q回内部堆结构中Q可能会被适当的处?比如和其他空闲空间合q成更大的空闲空?Q以更适合下一ơ内存分配申诗?br />q套复杂的分配机制实际上相当于一个内存分配的~冲?Cache)Q用这套机制有如下若干原因Q?
1. pȝ调用可能不支持Q意大的内存分配。有些系l的pȝ调用只支持固定大及其倍数的内存请?按页分配)Q这L话对于大量的内存分cL说会造成费?br />2. pȝ调用甌内存可能是代h늚。系l调用可能涉及用h和核心态的转换?
3. 没有理的内存分配在大量复杂内存的分配释放操作下很容易造成内存片?
堆和栈的Ҏ
从以上知识可知,栈是pȝ提供的功能,特点是快速高效,~点是有限制Q数据不灉|Q而栈是函数库提供的功能,特点是灵zL便,数据适应面广泛,但是效率有一定降低。栈是系l数据结构,对于q程/U程是唯一的;堆是函数库内部数据结构,不一定唯一。不同堆分配的内存无法互相操作。栈I间分静态分配和动态分配两U。静态分配是~译器完成的Q比如自动变?auto)的分配。动态分配由alloca函数完成。栈的动态分配无需释放(是自动的)Q也没有释攑և数。ؓ可移植的E序赯Q栈的动态分配操作是不被鼓励的!堆空间的分配L动态的Q虽然程序结束时所有的数据I间都会被释攑֛pȝQ但是精的甌内存/释放内存匚w是良好程序的基本要素?
所以计机中的堆和栈经常时放一块讲?
nod 一般不是必要就不要动态创建,最讨厌把new出来的东西当局部变量用Q?br />用万了马上delete 的做?
理由
1.栈分配比堆快Q只需要一条指令就呢给配所有的局部变?
2.栈不会出现内存碎?
3。栈对象好管?
当然Q某些情况下也要那么?比如
1.对象很大
2.对象需要在某个特定的时L造或析够
3.cd允许对象动态创?比如VCL的大多数c?
当然Q必ȝ堆对象时也不能躲?br />
http://kb.csdn.net/.net/Articles/200605/80f93200-6a0c-4e21-82d8-4212844da589.html
]]>
成员函数的重载、覆盖(overrideQ与隐藏很容易淆,C++E序员必要搞清楚概念,否则错误防不胜阌Ӏ?span>
成员函数被重载的特征Q?span>
Q?span>1Q相同的范围Q在同一个类中)Q?span>
Q?span>2Q函数名字相同;
Q?span>3Q参C同;
Q?span>4Q?span>virtual关键字可有可无?/span>
覆盖是指zcd数覆盖基cd敎ͼ特征是:
Q?span>1Q不同的范围Q分别位于派生类与基c)Q?span>
Q?span>2Q函数名字相同;
Q?span>3Q参数相同;
Q?span>4Q基cd数必Lvirtual关键字?span>
CZ
#include <iostream.h> class Base { public: void f(int x){ cout << "Base::f(int) " << x << endl; } void f(float x){ cout << "Base::f(float) " << x << endl; } virtual void g(void){ cout << "Base::g(void)" << endl;} };
|
class Derived : public Base { public: virtual void g(void){ cout << "Derived::g(void)" << endl;} };
|
void main(void) { Derived d; Base *pb = &d; pb->f(42); // Base::f(int) 42 pb->f( pb->g(); // Derived::g(void) } |
CZ
本来仅仅区别重蝲与覆盖ƈ不算困难Q但?span>C++的隐藏规则问题复杂性陡然增加。这?#8220;隐藏”是指zcȝ函数屏蔽了与其同名的基类函数Q规则如下:
Q?span>1Q如果派生类的函C基类的函数同名,但是参数不同。此Ӟ不论有无virtual关键字,基类的函数将被隐藏(注意别与重蝲hQ?span>
Q?span>2Q如果派生类的函C基类的函数同名,q且参数也相同,但是基类函数没有virtual关键字。此Ӟ基类的函数被隐藏Q注意别与覆盖淆)?/span>
CZE序
Q?span>1Q函?span>Derived::f(float)覆盖?span>Base::f(float)?span>
Q?span>2Q函?span>Derived::g(int)隐藏?span>Base::g(float)Q而不是重载?span>
Q?span>3Q函?span>Derived::h(float)隐藏?span>Base::h(float)Q而不是覆盖?span>
#include <iostream.h> class Base { public: virtual void f(float x){ cout << "Base::f(float) " << x << endl; } void g(float x){ cout << "Base::g(float) " << x << endl; } void h(float x){ cout << "Base::h(float) " << x << endl; } }; |
class Derived : public Base { public: virtual void f(float x){ cout << "Derived::f(float) " << x << endl; } void g(int x){ cout << "Derived::g(int) " << x << endl; } void h(float x){ cout << "Derived::h(float) " << x << endl; } }; |
CZ
据作者考察Q很?span>C++E序员没有意识到?#8220;隐藏”q回事。由于认识不够深刻,“隐藏”的发生可谓神出鬼没,常常产生令hqh的结果?span>
CZ
void main(void) { Derived d; Base *pb = &d; Derived *pd = &d; // Good : behavior depends solely on type of the object pb->f( pd->f(
// Bad : behavior depends on type of the pointer pb->g( pd->g(
// Bad : behavior depends on type of the pointer pb->h( pd->h( } |
CZ
隐藏规则引v了不麻烦。示?chsdate w:st="on" isrocdate="False" islunardate="False" day="3" month="2" year="2008">8-2-3E序中,语句pd->f(10)的本意是惌用函?span>Base::f(int)Q但?span>Base::f(int)不幸?span>Derived::f(char *)隐藏了。由于数?span>10不能被隐式地转化为字W串Q所以在~译时出错?span>
class Base { public: void f(int x); }; |
class Derived : public Base { public: void f(char *str); }; |
void Test(void) { Derived *pd = new Derived; pd->f(10); // error } |
CZ
从示?chsdate w:st="on" isrocdate="False" islunardate="False" day="3" month="2" year="2008">8-2-3看来Q隐藏规则似乎很愚蠢。但是隐藏规则至有两个存在的理由:
u 写语?span>pd->f(10)的h可能真的惌?span>Derived::f(char *)函数Q只是他误将参数写错了。有了隐藏规则,~译器就可以明确指出错误Q这未必不是好事。否则,~译器会静悄悄地错错Q程序员很隑֏现这个错误,下根?span>
u 假如c?span>Derived有多个基c(多重l承Q,有时搞不清楚哪些基类定义了函?span>f。如果没有隐藏规则,那么pd->f(10)可能会调用一个出乎意料的基类函数f。尽隐藏规则看h不怎么有道理,但它的确能消灭这些意外?span>
CZ
class Derived : public Base
{
public:
void f(char *str);
void f(int x) { Base::f(x); }
};
标准库?/strong>
标准库中提供了C++E序的基本设施。虽然C++标准库随着C++标准折腾了许多年Q直到标准的出台才正式定型,但是在标准库的实C却很令hƣ慰得看到多U实玎ͼq且已被实践证明为有工业U别强度的佳作。?/p>
1、 Dinkumware C++ Library
参考站点:http://www.dinkumware.com
P.J. Plauger~写的高品质的标准库。P.J. Plauger博士是Dr. Dobb'sE序设计杰出奖的获得者。其~写的库长期被Microsoft采用Qƈ且最qBorland也取得了其OEM的licenseQ在其C/C+ +的品中采用Dinkumware的库。?/p>
2、 RogueWave Standard C++ Library
参考站点:http://www.roguewave.com/
q个库在Borland C++ Builder的早期版本中曄被采用,后来被其他的库给替换了。笔者不推荐使用。?/p>
3、SGI STL
参考站点:http://www.roguewave.com/
SGI公司的C++标准模版库。?/p>
4、STLport
参考站点:http://www.stlport.org/
SGI STL库的跨^台可UL版本。?/p>
准标准库——Boost
Boost 库是一个经q千锤百点{可UL、提供源代码的C++库,作ؓ标准库的后备Q是C++标准化进E的发动Z一。 Boost库由C++标准委员会库工作l成员发P在C++C中媄响甚大,其成员已q?000人。 Boost库ؓ我们带来了最新、最酗最实用的技术,是不折不扣的"?标准库。?/p>
Boost中比较有名气的有q么几个库:
Regex
正则表达式库
Spirit
LL parser frameworkQ用C++代码直接表达EBNF
Graph
囄件和法
Lambda
在调用的地方定义短小匿名的函数对象,很实用的functional功能
concept check
查泛型编E中的concept
Mpl
用模板实现的元编E框架?/p>
Thread
可移植的C++多线E库
Python
把C++cd函数映射到Python之中
Pool
内存池管理?/p>
smart_ptr
5个智能指针,学习指针必读Q一份不错的参考是来自CUJ的文章:
Smart Pointers in Boost,哦,q篇文章可以查到QCUJ是提供在U浏览的。中文版见笔者在《Dr. Dobb's Journal软g研发杂志》第7辑上的译文。?/p>
Boost M来说是实用h值很高,质量很高的库。ƈ且由于其对跨q_的强调,Ҏ准C++的强调,是编写^台无养ICC++的开发者必备的工具。但是Boost 中也有很多是实验性质的东西,在实际的开发中实用需要}慎。ƈ且很多Boost中的库功能堪U对语言功能的扩展,其构造用精巧的手法Q不要N然的p旉研读。Boost另外一面,比如Graphq样的库则是h工业强度Q结构良好,非常值得研读的精品代码,q且也可以放心的在品代码中多多利用。?/p>
参考站点:http://www.boost.orgQ国内镜像:http://www.c-view.org/tech/lib/boost/index.htmQ?/p>
GUI
在众多C++的库中,GUI部分的库是比较J荣Q也比较引h注目的。在实际开发中QGUI库的选择也是非常重要的一件事情,下面我们lD一下可选择的GUI库,各自的特点以及相兛_L支持。?/p>
1、 MFC
大名鼎鼎的微软基cdQMicrosoft Foundation ClassQ。大凡学qVC++的h都应该知道这个库。虽然从技术角度讲QMFC是不大漂亮的Q但是它构徏于Windows API 之上Q能够ɽE序员的工作更容?~程效率高,减少了大量在建立 Windows E序时必ȝ写的代码Q同时它q提供了所有一般 C++ ~程的优点,例如l承和封装。MFC ~写的程序在各个版本的Windows操作pȝ上是可移植的Q例如,在 Windows 3.1下编写的代码可以很容易地UL刊WWindows NT 或 Windows 95 上。但是在最q发展以及官Ҏ持上日渐势微。?/p>
2、 QT
参考网站:http://www.trolltech.com
Qt 是Trolltech公司的一个多q_的C++囑Ş用户界面应用E序框架。它提供l应用程序开发者徏立艺术的图形用L面所需的所用功能。Qt是完全面向对象的很容易扩展,q且允许真正地组件编E。自?996q早些时候,Qtq入商业领域Q它已经成ؓ全世界范围内数千U成功的应用E序的基。Qt也是行的Linux桌面环境KDE 的基Q同时它q支持Windows、Macintosh、Unix/X11{多U^台。?/p>
3、WxWindows
参考网站:http://www.wxwindows.org/
跨^台的GUI库。因为其cdơ极像MFCQ所以有文章介绍从MFC到WxWindows的代码移植以实现跨^台的功能。通过多年的开发也是一个日完善的 GUI库,支持同样不弱于前面两个库。ƈ且是完全开放源代码的。新q的C++ Builder X的GUI设计器就是基于这个库的。?/p>
4、Fox
开放源代码的GUI库。作者从自己亲n的开发经验中得出了一个理想的GUI库应该是什么样子的感受出发Q从而开始了对这个库的开发。有兴趣的可以尝试一下。?/p>
参考网站:http://www.fox-toolkit.org/
5、 WTL
ZATL的一个库。因Z用了大量ATL的轻量手法Q模板等技术,在代码尺寸,以及速度优化斚w做得非常C。主要面向的使用体是开发COM轻量U供|络下蝲的可视化控g的开发者。?/p>
6、 GTK
参考网站:http://gtkmm.sourceforge.net/
GTK是一个大名鼎鼎的C的开源GUI库。在Linux世界中有Gnomeq样的杀手应用。而GTK是q个库的C++装版本。?/p>
|络通信?/p>
ACE
参考网站:http://www.cs.wustl.edu/~schmidt/ACE.html
ACE|络~程开发论坛:http://www.acejoy.com
C+ +库的代表Q超重量U的|络通信开发框架。ACE自适配通信环境QAdaptive Communication EnvironmentQ是可以自由使用、开放源代码的面向对象框Ӟ在其中实C许多用于q发通信软g的核心模式。ACE提供了一l丰富的可复用C++ 包装外观QWrapper FacadeQ和框架lgQ可跨越多种q_完成通用的通信软gdQ其中包括:事g多\分离和事件处理器分派、信号处理、服务初始化、进E间通信、共享内存管理、消息\由、分布式服务动态(重)配置、ƈ发执行和同步Q等{。?/p>
StreamModule
参考网站:http://www.omnifarious.org/StrMod/
设计用于化编写分布式E序的库。尝试着使得~写处理异步行ؓ的程序更ҎQ而不是用同步的外壛_起异步的本质。?/p>
SimpleSocket
参考网站:http://home.hetnet.nl/~lcbokkers/simsock.htm
q个cd让编写基于socket的客?服务器程序更加容易。?/p>
A Stream Socket API for C++
参考网站:http://www.pcs.cnu.edu/~dgame/sockets/socketsC++/sockets.html
又一个对Socket的封装库。?/p>
XML
Xerces
参考网站:http://xml.apache.org/xerces-c/
Xerces-C++ 是一个非常健壮的XML解析器,它提供了验证Q以及SAX和DOM API。XML验证在文档类型定?Document Type DefinitionQDTD)斚w有很好的支持Qƈ且在2001q?2月增加了支持W3C XML Schema 的基本完整的开放标准。?/p>
XMLBooster
参考网站:http://www.xmlbooster.com/
q个库通过产生特制的parser的办法极大的提高了XML解析的速度Qƈ且能够生相应的GUIE序来修改这个parser。在DOM和SAX两大主XML解析办法之外提供了另外一个可行的解决Ҏ。?/p>
Pull Parser
参考网站:http://www.extreme.indiana.edu/xgws/xsoap/xpp/
q个库采用pullҎ的parser。在每个SAX的parser底层都有一个pull的parserQ这个xpp把这层暴露出来直接给大家使用。在要充分考虑速度的时候值得试。?/p>
Xalan
参考网站:http://xml.apache.org/xalan-c/
Xalan是一个用于把XML文档转换为HTMLQ纯文本或者其他XMLcd文档的XSLT处理器。?/p>
CMarkup
参考网站:http://www.firstobject.com/xml.htm
q是一U用EDOM的XML解析器。在很多思\上面非常灉|实用。值得大家在DOM和SAX之外L一点灵感。?/p>
libxml++
http://libxmlplusplus.sourceforge.net/
libxml++是对著名的libxml XML解析器的C++装版本
U学计算
Blitz++
参考网站:http://www.oonumerics.org/blitz/
Blitz++ 是一个高效率的数D函数库Q它的设计目的是希望建立一套既具像C++ 一h便,同时又比Fortran速度更快的数D环境。通常Q用C++所写出的数值程序,比 Fortran?0%左右Q因此Blitz++正是要改掉这个缺炏V方法是利用C++的template技术,E序执行甚至可以比Fortran更快。 Blitz++目前仍在发展中,对于常见的SVDQFFTsQQMRES{常见的U性代数方法ƈ不提供,不过使用者可以很Ҏ地利用Blitz++所提供的函数来构徏。?/p>
POOMA
参考网站:http://www.codesourcery.com/pooma/pooma
POOMA是一个免费的高性能的C++库,用于处理q行式科学计。POOMA的面向对象设计方便了快速的E序开发,对ƈ行机器进行了优化以达到最高的效率Q方便在工业和研I环境中使用。?/p>
MTL
参考网站:http://www.osl.iu.edu/research/mtl/
Matrix Template Library(MTL)是一个高性能的泛型组件库Q提供了各种格式矩阵的大量线性代数方面的功能。在某些应用使用高性能~译器的情况下,比如Intel的编译器Q从产生的汇~代码可以看出其与手写几乎没有两L效能。?/p>
CGAL
参考网站:www.cgal.org
Computational Geometry Algorithms Library的目的是把在计算几何斚w的大部分重要的解x案和Ҏ以C++库的形式提供l工业和学术界的用户。?/p>
游戏开发?/p>
Audio/Video 3D C++ Programming Library
参考网站:http://www.galacticasoftware.com/products/av/
AV3D是一个跨q_Q高性能的C++库。主要的Ҏ是提供3D囑ŞQ声效支持(SB,以及S3MQ,控制接口Q键盘,鼠标和遥感)QXMS。?/p>
KlayGE
参考网站:http://home.g365.net/enginedev/
国内游戏开发高手自qC++开发的游戏引擎。KlayGE是一个开放源代码、跨q_的游戏引擎,q用Python作脚本语a。KlayGE在LGPL协议下发行。感谢龚敏敏先生Z国游戏开发事业所做出的A献。?/p>
OGRE
参考网站:http://www.ogre3d.org
OGRE Q面向对象的囑Ş渲染引擎Q是用C++开发的Q用灵zȝ面向对象3D引擎。它的目的是让开发者能更方便和直接地开发基?Dg讑֤的应用程序或游戏。引擎中的类库对更底层的pȝ库(如:Direct3D和OpenGLQ的全部使用l节q行了抽象,q提供了Z现实世界对象的接口和其它cR?/p>
U程
C++ Threads
参考网站:http://threads.sourceforge.net/
q个库的目标是给E序员提供易于用的c,q些c被l承以提供在Linux环境中很隄到的大量的线E方面的功能。?/p>
ZThreads
参考网站:http://zthread.sourceforge.net/
一个先q的面向对象Q跨q_的C++U程和同步库。?/p>
序列化?br /> s11n
参考网站:http://s11n.net/
一个基于STL的C++库,用于序列化PODQSTL容器以及用户定义的类型。?br /> Simple XML Persistence Library
参考网站:http://sxp.sourceforge.net/
q是个把对象序列化ؓXML的轻量的C++库。?/p>
字符串?/p>
C++ Str Library
参考网站:http://www.utilitycode.com/str/
操作字符串和字符的库Q支持Windows和支持gcc的多U^台。提供高度优化的代码Qƈ且支持多U程环境和UnicodeQ同时还有正则表辑ּ的支持。?/p>
Common Text Transformation Library
参考网站:http://cttl.sourceforge.net/
q是一个解析和修改STL字符串的库。CTTL substringcd以用来比较,插入Q替换以及用EBNF的语法进行解析。?/p>
GRETA
参考网站:http://research.microsoft.com/projects/greta/
q是由微软研I的研Ih员开发的处理正则表达式的库。在型匚w的情况下有非怼U的表现。?/p>
l合
P::Classes
参考网站:http://pclasses.com/
一个高度可UL的C++应用E序框架。当前关注类型和U程安全的signal/slot机制Qi/opȝ包括Z插g的网l协议透明的i/o架构Q基于插件的应用E序消息日志框架Q访问sql数据库的cȝ{。?/p>
ACDK - Artefaktur Component Development Kit
参考网站:http://acdk.sourceforge.net/
q是一个^台无关的C++lg框架Q类gJava或?NET中的框架Q反机ӞU程QUnicodeQ废料收集,I/OQ网l,实用工具QXMLQ等{)Q以及对Java, Perl, Python, TCL, Lisp, COM 和 CORBA的集成。?/p>
dlib C++ library
参考网站:http://www.cis.ohio-state.edu/~kingd/dlib/
各种各样的类的一个综合。大整数QSocketQ线E,GUIQ容器类,以及览目录的API{等。?/p>
Chilkat C++ Libraries
参考网站:http://www.chilkatsoft.com/cpp_libraries.asp
q是提供zipQe-mailQ编码,S/MIMEQXML{方面的库。?/p>
C++ Portable Types Library (PTypes)
参考网站:http://www.melikyan.com/ptypes/
q是STL的比较简单的替代品,以及可移植的多线E和|络库。?/p>
LFC
参考网站:http://lfc.sourceforge.net/
哦,q又是一个尝试提供一切的C++库?/p>
其他库?/p>
Loki
参考网站:http://www.moderncppdesign.com/
哦,你可能抱怨我早该和Boost一起介l它Q一个实验性质的库。作者在loki中把C++模板的功能发挥到了极致。ƈ且尝试把cM设计模式q样思想层面的东襉K过库来提供。同时还提供了智能指针这h较实用的功能。?/p>
ATL
ATL(Active Template Library)是一l小巧、高效、灵zȝc,q些cMؓ创徏可互操作的COMlg提供了基本的设施。?/p>
FC++: The Functional C++ Library
q个库提供了一些函数式语言中才有的要素。属于用库来扩充语言的一个代表作。如果想要在OOP之外L另一分的乐趣Q可以去看看函数式程序设计的世界。大师 Peter Norvig在?Teach Yourself Programming in Ten Years"一文中将函数式语a列ؓ臛_应当学习?cȝE语a之一。?/p>
FACT!
参考网站:http://www.kfa-juelich.de/zam/FACT/start/index.html
另外一个实现函数式语言Ҏ的库?/p>
Crypto++
提供处理密码Q消息验证,单向hashQ公匙加密系l等功能的免费库。?/p>
q有很多非常Ȁ动h心或者是极其实用的C++库,限于我们的水q以及文章的幅不能包括q来。在对于q些已经包含q来的库的介l中Q由于ƈ不是每一个我们都使用q,所以难免有偏颇之处Q请读者见谅。?/p>
资源|站
正如我们可以通过计算机历史上的重要h物了解计机史的发展QC++相关人物的网站也可以使我们得到最有h值的参考与借鉴Q下面的人物我们认ؓ没有介绍的必要,只因下面的h物在C++领域的地位众所周知Q我们只相关的资源q行|列以供读者学习,他们有的工作于贝实验室Q有的工作于知名~译器厂商,有的在不断推q语a的标准化Q有的ؓ读者撰写了多部千古奇作......
Bjarne Stroustrup http://www.research.att.com/~bs/
Stanley B. Lippman
http: //blogs.msdn.com/slippman/ 中文版 http: //www.zengyihome.net/slippman/index.htm
Scott Meyers http://www.aristeia.com/
David Musser http://www.cs.rpi.edu/~musser/
Bruce Eckel http://www.bruceeckel.com
Nicolai M. Josuttis http://www.josuttis.com/
Herb Sutter http://www.gotw.ca/
Andrei Alexandrescu http://www.moderncppdesign.com/
4. virtual void Initiate(void);
数据初始化?初始化数据实体的数据.
5 Q?span lang=EN-US> virtual void Reset(void);
数据复位操作。把数据实体复位到某一状?span lang=EN-US>.
5. virtual CEntity * Clone(void) const;
克隆数据实体. q个函数一般这样实?span lang=EN-US>: return new CEntity(*this);
6. virtual void Serialize(CArchive& ar);
数据串行?span lang=EN-US>. 以实现数据实体左右移方式的对数据实体赋?span lang=EN-US>,保存{操?span lang=EN-US>. 常把其与CMemFile一起?span lang=EN-US>,感觉效果很好.唯一不的是解决数据实体版本升时的数据一致性的问题很麻?span lang=EN-US>.
7. virtual BOOL DataSet(const CEntity& ent);
h数据,实现数据实体之间的赋值操?span lang=EN-US>.q个函数主要是ؓ了解决上一所提的问题( C++随笔关于virtual poperator = ( 05-22 01:09) ). 可以把他设ؓprotectedcd, ?span lang=EN-US>operator=l合h使用, ?span lang=EN-US>poperator =调用.
8. const CEntity& operator=(const CEntity& ent);
赋值操?span lang=EN-US>.在派生类中也会重?span lang=EN-US>operator=, 不是重蝲基类?span lang=EN-US>operator=.
9. 另外如果存在数据比较的话, 会重?span lang=EN-US>operator==操作W?span lang=EN-US>.
friend bool operator==(const CEntity& ent1, const CEntity& ent2);
friend bool operator!=(const CEntity& ent1, const CEntity& ent2);
谢谢x~~~
以下附三相电电压数据实体部分实C?span lang=EN-US>:
class CThreePhaseEntity: public CEntity
{
public:
CThreePhaseEntity ();
CThreePhaseEntity (const CSixPhaseEntity& ent);
~CSixPhaseEntity();
public:
CString GetTypeID(void) const;
void Initiate(void);
void Reset(void);
public:
CEntity * Clone(void) const;
void Serialize(CArchive& ar);
BOOL DataSet(const CEntity& ent);
public:
const CSixPhaseEntity& operator=(const CSixPhaseEntity& ent);
friend bool operator==(const CSixPhaseEntity& ent1, const CSixPhaseEntity& ent2);
friend bool operator!=(const CSixPhaseEntity& ent1, const CSixPhaseEntity& ent2);
public:
// 获取三相数据 , 内联函数
const float& GetSixPhaseData(int nDateType, int nPhaseMark) const;
// 修改三相数据 , 内联函数
void SetSixPhaseData(int nDataType, int nPhaseMark, const float& fData);
private:
float m_gfRange[3]; // q?/span> ,
float m_gfPhase[3]; // 怽 ,
float m_gfFrequency[3]; // 频率
};
///******cpp 文g
CThreePhaseEntity:: CThreePhaseEntity ()
{
Initiate();
}
CThreePhaseEntity:: CThreePhaseEntity (const CThreePhaseEntity & ent)
{
for(int i=0; i<3; i++)
{
m_gfRange[i] = ent.m_gfRange[i];
m_gfPhase[i] = ent.m_gfPhase[i];
m_gfFrequency[i] = ent.m_gfFrequency[i];
}
}
CThreePhaseEntity::~ CThreePhaseEntity ()
{
}
CString CThreePhaseEntity::GetTypeID(void) const
{
return _T("ENT_THREEPHASE ");
}
void CThreePhaseEntity::Initiate()
{
for(int i=0; i<3; i++)
{
m_gfRange[i] =
m_gfPhase[i] =
m_gfFrequency[i] =
}
}
void CThreePhaseEntity::Reset(void)
{
for(int i=0; i<3; i++)
{
m_gfRange[i] =
m_gfFrequency[i] =
}
m_ gfPhase [0] =
m_ gfPhase [1] =
m_ gfPhase [2] =
}
void CThreePhaseEntity::Serialize(CArchive& ar)
{
if(ar.IsStoring())
{
for(int i=0; i<3; i++)
{
ar<<m_gfRange[i]<<m_gfPhase[i]<<m_gfFrequency[i];
}
}
else
{
for(int i=0; i<3; i++)
{
ar>>m_gfRange[i]>>m_gfPhase[i]>>m_gfFrequency[i];
}
}
}
BOOL CThreePhaseEntity::DataSet(const CEntity& ent)
{
if(GetTypeID() != ent.GetTypeID()) return FALSE;
const CThreePhaseEntity * pEnt = reinterpret_cast<const CThreePhaseEntity *>(&ent);
(*this) = (*pEnt);
return TRUE;
}
CEntity * CThreePhaseEntity::Clone(void) const
{
return new CThreePhaseEntity (*this);
}
const CThreePhaseEntity & CThreePhaseEntity::operator=(const CThreePhaseEntity & ent)
{
if(this == &ent) return *this;
for(int i=0; i<3; i++)
{
m_gfRange[i] = ent.m_gfRange[i];
m_gfPhase[i] = ent.m_gfPhase[i];
m_gfFrequency[i] = ent.m_gfFrequency[i];
}
return *this;
}
bool operator==(const CThreePhaseEntity & ent1, const CThreePhaseEntity & ent2)
{
for(int i=0; i<3; i++)
{
if(ent1.m_gfRange[i] != ent2.m_gfRange[i]) return false;
if(ent1.m_gfPhase[i] != ent2.m_gfPhase[i]) return false;
if(ent1.m_gfFrequency[i] != ent2.m_gfFrequency[i]) return false;
}
return true;
}
bool operator!=(const CThreePhaseEntity & ent1, const CThreePhaseEntity & ent2)
{
return (ent1 == ent2) ? false : true;
}
CEntity::CEntity(char flag)
{
m_flag = flag;
cout<<"constructing entity "<<m_flag<<endl;
m_data = new char[100];
}
CEntity::~CEntity()
{
cout<<"destructing entity "<<m_flag<<endl;
delete[] m_data;
}
以上q个cL没什么问题的Q但是看以下的调用:
int main(int argc, char* argv[])
{
CEntity * a = new CEntity('a');
delete a;
void * b = new CEntity('b');
delete b;
return 0;
}
其输ZؓQ?nbsp;constructing entity a
destructing entity a
constructing entity b
可见Qdelete b 的时候没有释放m_data所指向的内存,没有执行析构函数?nbsp;