??xml version="1.0" encoding="utf-8" standalone="yes"?>久久人人爽人人爽人人爽,精品久久久久久国产牛牛app,久久人人爽人人爽人人片AV高清 http://www.shnenglu.com/zliner/archive/2007/04/15/21942.html依旧的博?/dc:creator>依旧的博?/author>Sun, 15 Apr 2007 05:08:00 GMThttp://www.shnenglu.com/zliner/archive/2007/04/15/21942.htmlhttp://www.shnenglu.com/zliner/comments/21942.htmlhttp://www.shnenglu.com/zliner/archive/2007/04/15/21942.html#Feedback0http://www.shnenglu.com/zliner/comments/commentRss/21942.htmlhttp://www.shnenglu.com/zliner/services/trackbacks/21942.html
在WinMain()函数中,E序所q行的最重要工作是注册窗口类Q从而把自定义的H口q程提供lWindows。然后程序调用Windows创徏和显C窗口,由此启动同用L交互q程。在消息循环中,E序不断取得消息Q但q不q行处理Q而是其发回WindowsQ由Windows消息发l相应的H口q程。消息@环的作用在于控制生命期,如果没有消息循环Q进E将立即l束?

在较高层ơ上来看Q一个可扩展的系l会l模块提供资源和自由Q而模块应当配合系l的整体l构。程序执行时QWindows会ؓ其创E,分配资源Qƈ调用WinMain()。WinMain()是进E入口,也是q程出口Q在此期间进E可以做M事情Q但是ؓ了用Windows提供的各U便利,它必ȝ合WindowsE序模型Q将自己的运行结合到Windows环境中。作E出口,WinMain()军_着E序生命期。一个提供窗口过E而等待Windows调用的程序如何维持和l束自己的生命期呢,应该由消息来军_。当q程没有要处理的消息Ӟ它应该等待,所以WinMain()必须知道有没有消息,Windows发给H口q程的消息不能绕qWinMain()Q当q程收到特定的消息时Q它l束生命期,所以WinMain()q应该了解消息的内容。这正是GetMessage()所做的Q如果取不到消息阻塞,如果取到WM_QUIT消息p?Q结束消息@环。那么如果取到普通的消息呢,由WinMain()直接调用H口q程不可以吗Q这U做法有悖于E序由Windows调用的基本思想Q而实际上也会出现问题。一个窗口程序可能有很多H口c,一些窗口类及其H口q程是程序自定义的,另一些则是在Windows内部定义的,E序看不到其H口q程Q比如各U控件窗口。窗口程序运行v来以后,q些H口cM盔R合,它们通信的方式就是消息。由于消息指向的H口q程可能是自定义的,也可能是Windows内部的,只有Windows才能把它们都送到目的圎ͼq保持发送方式的一致性。所以WinMain()取到消息后,通过DispatchMessage()其发回WindowsQ由Windows为其调用适当的窗口过E,直到H口q程调用后返回WindowsQDispatchMessage()才返回?Windows调用H口q程之后控制首先q回WindowsQ由WinMain()调用H口q程之后控制保持在程序中Q这U区别是否也有作用?不过l我试验Q在一个Win32 SDK的HelloE序中改由WinMain()调用H口q程Q没有发C么问?

 
参考资料:

1.《WindowsE序设计?Charles Petzold ?北京博RU技发展有限公司 ?北大出版C?

]]>
动态链接引L内存理问题http://www.shnenglu.com/zliner/archive/2007/01/28/18108.html依旧的博?/dc:creator>依旧的博?/author>Sun, 28 Jan 2007 06:02:00 GMThttp://www.shnenglu.com/zliner/archive/2007/01/28/18108.htmlhttp://www.shnenglu.com/zliner/comments/18108.htmlhttp://www.shnenglu.com/zliner/archive/2007/01/28/18108.html#Feedback0http://www.shnenglu.com/zliner/comments/commentRss/18108.htmlhttp://www.shnenglu.com/zliner/services/trackbacks/18108.html如果在VC中创Z个控制台的EXE和一个Win32的DLLQ从DLL中导Z个函敎ͼ该函数用new分配一块内存,q回其指针,然后在EXE中调用该函数Q获得返回的指针Q用delete释放q块内存Q就会引发断a错误?br />
产生q个问题的原因是QEXE和DLL中分别静态链接了Cq行时库Q从而new和deleteq算W来自Cq行时库的不同版本。Cq行时库在管理堆内存Ӟ会用一些全局变量来跟t内存分配情况,因此E序中链接的Cq行时库必须唯一Q否则就会引起不一致?br />
解决的办法很单:在EXE和DLL中都动态链接Cq行时库Q也是在工E设|的Link面板选择"忽略所有默认的?Q再加入msvcrt.lib?br />
对这个问题有两种错误的观炚w要澄清:一U以为EXE和DLL有不同的堆,实际上DLLL被映到加蝲它的q程的地址I间Q它没有自己的堆Q一U以为DLL和EXE相对于不同的起始地址Q动态链接的地址映射机制引v了前面的问题Q实际上DLL是和OBJ一L目标模块Q每个目标模块都有自q起始地址Q但是链接成加蝲模块以后׃l一C个v始地址Q一个目标模块对其它模块的引用在链接前是以符h式表C的Q链接后会被修改成地址方式。静态链接和动态链接都会保证:加蝲模块是统一~址的?br />
参考资料:
1. http://topic.csdn.net/t/20020714/19/873683.html
2. MSDN July 2000/Knowledge Base/Windows Development/Win32 Software Development Kit/HOWTO: Use the C Run-Time
3. 《操作系l-内核与设计原?W四??William Stallings 著,迎梅等?电子工业出版C?br />



]]>
错误码、异常和断言http://www.shnenglu.com/zliner/archive/2006/10/19/13886.html依旧的博?/dc:creator>依旧的博?/author>Thu, 19 Oct 2006 13:28:00 GMThttp://www.shnenglu.com/zliner/archive/2006/10/19/13886.htmlhttp://www.shnenglu.com/zliner/comments/13886.htmlhttp://www.shnenglu.com/zliner/archive/2006/10/19/13886.html#Feedback0http://www.shnenglu.com/zliner/comments/commentRss/13886.htmlhttp://www.shnenglu.com/zliner/services/trackbacks/13886.html 有两个比较基本的问题Q?br />
1. Z么要用异总曉K误码?

错误码的~点Q?span lang="EN-US">

1) 默认是可以忽略的Q因用函数时可以不处理其q回|从而错误处理要依赖于程序员的主动性,而不是程序机制的要求Q?/span>

2) 不能跨作用域传送,必须逐层向上转发Q即使中间没有对错误码进行重新定义;
 

使用异常可以解决解决q两个问题:

1) 异常默认是不可忽略的Q抛出的异常必须捕获Q否则就会报错;

2) 异常可以跨作用域传送,从而错误的发现和处理被很好地分d来;
 

 

2. 异常和断a的区别:
 

异常被捕获后可以不作处理Q程序从捕获位置l箋执行。而断a是完全无法忽略的Q程序在断言p|处立即终止。因此断a通常用于调试版本Q用来发现程序中的逻辑错误。虽然异怹能v到这L作用Q但是不应该用异总替断aQ?br />1) 如果发现了逻辑错误Q必M改程序,而不可能在程序中q行处理和恢复,所以不需要向外传送,没有必要使用异常?br />2) 使用断言的开销比异常小得多Q而且断言可以从发布版中完全去除?br /> 

异常用于处理正确E序中的q行期问?span lang="EN-US">(比如内存分配p|Q窗口创建失败,U程创徏p|Q打开文gp|)Q以可能恢复,而不是终止程序。对于运行异常,使用断言是非怸合适的Q理由很昄Q?br />1) 断言在发布版不v作用Q?br />2) 断言的处理方式不够友好;
3) q行异常不是E序错误Q没有必要报告源代码出错位置Q?br />


参考资料:

1.《C++~程规范-101条规则、准则与最佛_c?Herb SutterQAndrei Alexandrescu ?刘基??人民邮电出版C?br />2.《C++E序设计语言?Bjarne Stroustrup 著 裘宗燕 ?机械工业出版C?br />3.《C与C++中的异常处理?Robert Schmidt ?无情 ?http://download.pchome.net/development/reference/11135.html



]]>
观察者模?/title><link>http://www.shnenglu.com/zliner/archive/2006/09/10/12217.html</link><dc:creator>依旧的博?/dc:creator><author>依旧的博?/author><pubDate>Sun, 10 Sep 2006 04:53:00 GMT</pubDate><guid>http://www.shnenglu.com/zliner/archive/2006/09/10/12217.html</guid><wfw:comment>http://www.shnenglu.com/zliner/comments/12217.html</wfw:comment><comments>http://www.shnenglu.com/zliner/archive/2006/09/10/12217.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/zliner/comments/commentRss/12217.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/zliner/services/trackbacks/12217.html</trackback:ping><description><![CDATA[ <p>软g设计中会到q样的关p:一个对象依赖于另一个对象,必须Ҏ后者的状态更新自q状态,可以把后者称作目标对象,前者称作观察者对象。不但观察者依赖于目标Q当目标的状态改变时也要通知观察者,q就出现了双向的依赖。两个对象互怾赖的后果是它们必M起复用。如果一个目标有多个观察者,那么目标也依赖所有观察者,从而目标对象无法独立复用。如何消除目标和观察者之间的互相依赖呢?观察者模式帮助我们解册个问题?br /><br />观察者模式把目标对观察者的依赖q行抽象Q目标只知道自己有若干观察者,但不知道q些观察者具体是谁,可能有多个Q当目标状态改变时只要l这些观察者一个通知Q不必作更多的事情。这L标对观察者的依赖pC抽象和最,而目标对具体观察者的依赖被解除了?br /><br />cd如下Q?br /><br /><img height="1" src="/WebResource.axd?d=pLXXeGbWF7eXU8SMs2-GFZvUWY2JNH05dFx5YzJhGUYAYJAFEaTEq36NAhTPy7_KekvzDFwt8wvQWdByvJIGWdEq6x2KpKD80&t=632780334567500000" width="1" /><img height="340" alt="Observer.JPG" src="http://www.shnenglu.com/images/cppblog_com/zliner/Observer.JPG" width="448" border="0" /><br /><br />Subject对象保存一个Observer引用的列表,当我们让一个ConcreteObserver对象观察Subject对象Ӟ调用后者的Attach()ҎQ将前者的引用加入该列表中。当Subject对象状态改变时Q它调用自n的NotifyҎQ该Ҏ调用列表中每一个Observer的Update()Ҏ。一个ConcreteObserver只要重定义Update()p收到通知Q作为对通知的响应,Update()调用Subject对象的getStatus()获取数据Q然后更新自w。当不需要l观察时QConcreteObserver对象调用Subject对象的Detach()ҎQ其引用被从列表中移除?br /><br />解除目标对具体观察者的依赖以后Q很Ҏ增加新的具体观察者,因ؓ不受依赖的方面就可以自由变化Q而目标也可以独立地复用,因ؓ无所依赖的方面就可以不受影响?br /><br />以上主要考虑了一个目标有多个观察者的情况Q我们设法解除了目标对具体观察者的依赖Q具体观察者的U类和数目容易改变。有时候一个观察者观察多个目标也是有意义的,在前面的cd中,观察者对具体目标的依赖仍然存在,因此无法适应目标斚w的变化。怎样抽象q种依赖呢?使观察者只知道若干个目标会向自己发出通知Q而不知道q些目标具体是谁Q可能有多少个;在目标向观察者发送通知Ӟ一个自w的引用作ؓ参数Q然后观察者调用其抽象Ҏ可以获得目标状态。这׃得观察者对目标的依赖是抽象的,观察者对具体目标的依赖被解除了?br /><br />cd如下Q?br /><br /><img height="442" alt="Observer2.JPG" src="http://www.shnenglu.com/images/cppblog_com/zliner/Observer2.JPG" width="541" border="0" /><br /><br />参考资料:<br /><br />1.《设计模?可复用面向对象Y件的基础?Erich Gamma{著Q李英军{译 机械工业出版C?/p> <img src ="http://www.shnenglu.com/zliner/aggbug/12217.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/zliner/" target="_blank">依旧的博?/a> 2006-09-10 12:53 <a href="http://www.shnenglu.com/zliner/archive/2006/09/10/12217.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>创徏型模?/title><link>http://www.shnenglu.com/zliner/archive/2006/08/08/10981.html</link><dc:creator>依旧的博?/dc:creator><author>依旧的博?/author><pubDate>Tue, 08 Aug 2006 05:01:00 GMT</pubDate><guid>http://www.shnenglu.com/zliner/archive/2006/08/08/10981.html</guid><wfw:comment>http://www.shnenglu.com/zliner/comments/10981.html</wfw:comment><comments>http://www.shnenglu.com/zliner/archive/2006/08/08/10981.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/zliner/comments/commentRss/10981.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/zliner/services/trackbacks/10981.html</trackback:ping><description><![CDATA[ <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">Factory Method-创徏多种同类产品的工厂:</span> <br /> <br /> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">ZcM?/span> <span lang="EN-US">(</span> <span style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">一个抽象品及其所有具体?/span> <span lang="EN-US">)</span> <span style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">提供一个工厂,该类的每一U具体品由工厂中的一个方法创建。种U做法的~点是不易增加新的具体品,每增加一个具体品,工厂中就要增加一个方法,<span style="COLOR: #ff6600"><font color="#000000">q意味着工厂的所有用者都要重新编?/font></span>。可以用参数化的Ҏ来改q,工厂只提供一个接受参数的创徏函数Q参数的取值标志了某种具体产品Q在创徏函数中对参数q行判断Q根据不同的参数值创Z同的具体产品q返回。这减了增加具体产品的代P每增加一U具体品时只要修改工厂的创建函数的实现卛_?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">原来是用工厂的不同方法创Z同的具体对象Q现在是用同一个方法的不同参数创徏不同的具体对象。还可以用抽象工厂的不同zcL创徏不同的具体对象,q种做法比较W重.<br /><br /></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">Abstract Factory-可替换的工厂Q?/span> <br /> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">见参考资?<br /><br /><br />参考资料:<br /><br />1.《设计模?可复用面向对象Y件的基础?Erich Gamma{著Q李英军{译 机械工业出版C?br />2.《敏捯Y件开?原则Q模式与实践?Robert C.Martin?邓辉译  清华大学出版社<br /></p> <img src ="http://www.shnenglu.com/zliner/aggbug/10981.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/zliner/" target="_blank">依旧的博?/a> 2006-08-08 13:01 <a href="http://www.shnenglu.com/zliner/archive/2006/08/08/10981.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MVC模式和文?视图l构http://www.shnenglu.com/zliner/archive/2006/08/06/10881.html依旧的博?/dc:creator>依旧的博?/author>Sun, 06 Aug 2006 02:05:00 GMThttp://www.shnenglu.com/zliner/archive/2006/08/06/10881.htmlhttp://www.shnenglu.com/zliner/comments/10881.htmlhttp://www.shnenglu.com/zliner/archive/2006/08/06/10881.html#Feedback0http://www.shnenglu.com/zliner/comments/commentRss/10881.htmlhttp://www.shnenglu.com/zliner/services/trackbacks/10881.htmlMVC(Model-View-Controller)模式的基本思想是数据,昄和处理相分离。模?Model)负责数据理Q视?View)负责数据昄Q控制器(Controller)负责业务逻辑和响应策略?br>
从MVC的Ş成过E来看,最初只有模型和视图两个元素。模型封装了数据q提供操作接口,视图用来表现数据和接收用戯求。模型是独立的,而视图依赖于模型Q从模型获取数据q行昄Q向模型发送用戯求,q根据返回结果刷新自己?br>
需要用多个视图表现同一模型Ӟ情况发生了变化:一个视图修Ҏ据以后,不但本n要刷斎ͼ其他所有视图也要刷新。如果由该视N知其他视图Q它需要知道其他所有视图,׃每个视图都可能发Z改,每个视图都要知道其他所有视图,q种兌q于复杂Q不但难以维护,而且不便于增加新的视图。如果让模型通知所有视图更斎ͼ可能会媄响模型的独立性。用观察?Observer)模式可以解决上述矛盾Q从而实玎ͼ由模型通知视图Q而模型不依赖于具体的视图Q具体视图之间相互独立?br>
视图是用戯求的接收者,但不宜作求的处理者。因为界面是易变的,如果业务代码和界面代码放在一P频繁的界面修改可能会破坏比较E_的业务代码。将业务逻辑分离出来Q由一个控制器负责Q就是ؓ了避免这U干扰?br>
模型Q视囑֒控制器的基本协作关系如下?br>
MVC模式协作?gif

模型在状态变化的时候,直接通知所有视图,视图向模型查询状态数据,然后h自n。当用户发出操作Ӟ视图把消息发l控制器Q控制器按照业务逻辑q行处理Q需要查询或更新数据Ӟ控制器会调用模型。下面是一个更详细的示意图

MVC模式协作?.gif


同样的数据,可以有不同的昄和进行各U处理。显CZ仅是表现数据Q而处理是Ҏ用户h改变数据的过E,不但包含业务逻辑Q也要提供响应策略。响应策略由控制器负责,视图可以使用不同的控制器提供不同的响应方式,q是{略(Strategy)模式的应用?br>
此外QMVCq允许视囑ֵ套,通过使用l合(Composite)模式Q一致地处理l合视图和普通视图?br>
用多个视图表C个模型,在视图不变的情况下改变响应策略,允许视图嵌套Q这是MVC的三个主要特性。在内部l构上,MVC的主要关pLp察者模式,{略模式和组合模式给出的。由观察者模式确定的模型视图关系是其中最为重要的?br>
MVC模式有许多变体。前q结构中Q由模型通知视图hQ称Z动MVCQ如果由控制器更新模型以后通知视图Q称动MVCl构。在许多应用中,没有明显的控制器角色Q也没有视图嵌套。可见根据实际需要,构成MVC的三个模式上都可能出现变化。Web览器就是被动MVCl构的一个实例?img height=437 alt="" src="http://www.shnenglu.com/images/cppblog_com/zliner/Browser.gif" width=652 border=0>
“览器是一个交互程序,从概念上Ԍ它是׃l客戗一l解释器与一个管理它们的控制器所l成。控制器形成了浏览器的中心部Ӟ它解释鼠标点M键盘输入Qƈ且调用其他组件来执行用户指定的操作。例如,当用户键入一个URL或者点M个超文本引用Ӟ控制器调用一个客户从所需文档所在的q程服务器上取回该文档,q且调用解释器向用户昄该文档?font face="Times New Roman">每个览器必d含一个HTML解释器来昄文档Q其他解释器是可选的。HTML解释器的输入q合HTML语法的文档所l成Q输出由位于用户昄器上的格式版本文档所l成。解释器通过HTML规则转换成适合用户昄g的命令来处理版面l节。HTML解释器一个最重要的功能是包含可选项。解释器必须存储关于昄器上位置之间关系的信息和HTML文档中被瞄定的项。当用户用鼠标选定了一个项Q浏览器通过当前的光标位|和存储的位|信息来军_哪个被用户选定?/font>”(参考资?)


MFC的文?视图l构(Document/View architecture)是MVC模式的一U变体,下面讨论它是怎样实现的?br>
文档/视图l构没有体现业务逻辑和视囄分离Q但是将响应{略和视囑֌分开来。它主要包含四种对象Q?/p>

  1. 文档
  2. 视图
  3. 视图框架H口
  4. 文档模板

q里的视图框架窗口定义了视图对用戯入的响应方式Q而文档模板用来管理前三种对象的组合。文档,视图Q视图框架窗口三者是对应的,从而构成一个三元组。一个应用程序可能需要多个这L三元l,以实现文档的多视图,所以引入文档模板来表示该三元组。因为程序中可能使用多个文档模板QMFC用一个文档管理者对象来理它们?br>
在MFC中,应用E序和主框架H口是用来封装底层机制的对象Q文档,视图Q视图框架窗口和文档模板是用来构架文?视图l构的对象。应用程序通过文档理者来使用文档/视图l构?br>
如果要给文档增加一U视图,只需要增加一个文档模板;如果要改变一U视囄响应{略Q只要改变对应文档模板中的视图框架窗口?br>
<未完待箋>


参考资料:

1.《设计模?可复用面向对象Y件的基础?Erich Gamma{著Q李英军{译 机械工业出版C?br>2.《Java与模式?阎宏 电子工业出版C?br>3.  模型-视图-控制?/a> ( MSDN > 技术资源库 > 体系l构 > 使用 Microsoft .NET 的企业解x案模?nbsp;>W??Web 表示模式)
4. 《Java设计Q对象,UML和过E?Kirk Knoernschild 著,|英伟等?人民邮电出版C?br>5. 《计机|络与因特网?D.E.Comer ?徐良贤等?机械工业出版C?br>6.《深入解析MFC?中国电力出版C?br>7.《VC技术内q》第5?/ 希望电子出版C?/nobr>



]]>
用例分析基础http://www.shnenglu.com/zliner/archive/2006/06/01/8038.html依旧的博?/dc:creator>依旧的博?/author>Thu, 01 Jun 2006 09:18:00 GMThttp://www.shnenglu.com/zliner/archive/2006/06/01/8038.htmlhttp://www.shnenglu.com/zliner/comments/8038.htmlhttp://www.shnenglu.com/zliner/archive/2006/06/01/8038.html#Feedback0http://www.shnenglu.com/zliner/comments/commentRss/8038.htmlhttp://www.shnenglu.com/zliner/services/trackbacks/8038.html1. 一个用例可以有多个参与者,q且可以同时有多个参与者?br />用例和参与者的兌可以是双向的Q参与者和用例都可以发起通信?br />
2. 用例之间的基本关pLQ泛化,包含和扩展?br />用例A到B的泛化关p表CA和B是具体与抽象的关pR?br />用例A到B的包含关p表CA使用了B提供的功能?br />用例A到B的扩展关p表CA向B提供的可用的功能?br />但从A到B的包含关pd从B到A的扩展关pL不同的:
A包含B说明B是从A中分解出来的公共行ؓQB自n是独立的Q但对于A来说是不可缺的一部分?br />B扩展A说明B是从A中分解出来的变体行ؓQ必L定扩展点Q也是在基本用例中执行变体行ؓ的具体条件。B仅仅是A的补充,而不是不可缺的部分QB自n也不是独立的。A可以单独执行Q表C通常的情况,在特定的情况下,用B来补充它?br />抽象用例不能被实例化Q不能被实际执行Q它的作用在于更好地l织用例关系?br />



参考书Q?br />《UML用户指南?Grady BoochQJames RumbaughQIvar Jacobson?늻忠等?机械工业出版C?br />《统一软g开发过E?Ivar JacobsonQGrady BoochQJames Rumbaugh?周伯生等?机械工业出版C?br />



]]>
多操作系l的引导http://www.shnenglu.com/zliner/archive/2006/05/18/7362.html依旧的博?/dc:creator>依旧的博?/author>Thu, 18 May 2006 08:27:00 GMThttp://www.shnenglu.com/zliner/archive/2006/05/18/7362.htmlhttp://www.shnenglu.com/zliner/comments/7362.htmlhttp://www.shnenglu.com/zliner/archive/2006/05/18/7362.html#Feedback0http://www.shnenglu.com/zliner/comments/commentRss/7362.htmlhttp://www.shnenglu.com/zliner/services/trackbacks/7362.html 我曾l在有一个Windows XP的机器上另装一个Windows 2000Q结?000装完后XP不能启动了。后来上|看了一些资料,又几l试验,解决了这个问题。这里ȝ一下其中的原理Q这个现象很Ҏ在重装低版本pȝ后出玎ͼ而且弄清原理以后Q我们可以更自由地处理多pȝ安装的问题?br />
单个操作pȝ的引DE是q样的:首先Q主引导记录(MBR)被加载到内存q行Q它d盘分区?DPT)Q查扄一个活动分?可引导分?Q该分区的引导扇区存攄操作pȝ的引D录。然后,pȝ引导记录被加载到内存q行Q它从系l安装目录读取系l的启动文gQ将其加载执行,控制随后的启动过E?/span>

q里面涉及到一些程序和数据Q它们存攑֜不同的地方,在不同阶D运行。第一D늨序MBRQ它的数据是DPTQ它们存攑֜盘的主引导扇区。第二段E序是系l引D录,存放在系l所在分区的引导扇区。第三段E序是系l启动文Ӟ存放在系l所在分区系l安装目录中。这三段E序像接力跑一P前一D늨序的工作是加蝲后一D늨序,q把控制交给它?/span> 引导记录和启动文仉操作pȝ而不同, 是在安装时Ş成的Q每个系l的安装E序都把其引D录写入安装分区的引导扇区Q而启动文件是pȝ的一部分?/span>

上面的引DE有一个基本缺P是只能引导一个系l,q且只能引导装在W一zd分区的系l?br />
如果一个操作系l不在活动分区,那么该系l要被引导有三种办法Q改写MBRQ改写第一zd分区引导记录Q或把所在分为第一zd分区。最后一U做法是不方便的Q系l通常会改写前两段引导E序Q那么它在解册w引导问题的同时Q也不能破坏其他pȝ的引|q就引出了多pȝ地引导问题。常见的做法?/span>pȝ提供一个启动管理器接管引导q程。启动管理器能够获得机器上多个系l的引导记录Q从而可以根据用户选择启动不同的系l。系l在安装时改写磁盘第一zd分区的引D录,使启动管理器被作为第三段E序加蝲?/span>

如果启动理器能够知道机器上每个pȝ所在的分区Q就能获得该pȝ的引D录,从而可以引Dpȝ。但实际上,启动理器所属系l的引导记录是不能再ơ被加蝲的,必须Ҏ对待。同一pd的系l,也可能有cM的问题。所以启动管理器可能要了解机器上每个pȝ具体如何启动Q相应进行引对{这样只有让高版本的pȝ提供启动理器,因ؓ低版本的启动理器无法启动高版本pȝ?/span>2000/XP的启动管理器是OS Loader。它?8?000/XP的引导就是不同的Q对98是加?8引导记录的镜像文Ӟ?000/XP是加载HAL.DLL{文件。OS Loader在引导多pȝӞ对于windowspd的引导有Ҏ性,必须向下兼容?/span>

OS Loader的蝲体是ntldr文gQ它q行时还会读取一个配|文件boot.iniQ两个文仉存放在磁盘第一zd分区根目录。boot.ini记录了每个系l所在的分区Q每个版本的windows在安装时都会在boot.ini中填写有兌w的一V?000/XP在安装时都会更新OS Loader和重写第一zd分区的引D录,后安装者的两个E序才会被保留。如果后?000Q由于前q的OS Loader版本问题Q就可能无法引导XP?/span>



]]>
MFC的五U基本机?/title><link>http://www.shnenglu.com/zliner/archive/2006/05/15/7218.html</link><dc:creator>依旧的博?/dc:creator><author>依旧的博?/author><pubDate>Mon, 15 May 2006 11:33:00 GMT</pubDate><guid>http://www.shnenglu.com/zliner/archive/2006/05/15/7218.html</guid><wfw:comment>http://www.shnenglu.com/zliner/comments/7218.html</wfw:comment><comments>http://www.shnenglu.com/zliner/archive/2006/05/15/7218.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/zliner/comments/commentRss/7218.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/zliner/services/trackbacks/7218.html</trackback:ping><description><![CDATA[<p>我们知道MFC的作用在于封装Windows的编E接口,q提供应用程序框架的开发模式。ؓ了完成从前者到后者的q渡QMFC实现了几U基本机Ӟ它们是消息映,命o传递,q行时类信息(RTCI)Q动态创建和序列化?br><br>消息映射和命令传递是对SDKE序交互机制的封装。序列化是应用程序需要的一U基本特性,x数据保存到磁盘和从磁盘打开数据。通过RTCI和动态创建,可以把Y件的对象数据保存到磁盘,反过来从q些数据识别和恢复对象,从而实现对象的序列化。基于数据库的序列化机制和这U方式不同,应用E序和数据库之间有一个约定,以什么样的格式保存什么样的数据,再以同样的方式打开Qƈ且如何重建对象数据也定下来了Q在打开数据Ӟ应用E序不需要有适应性,不需要识别数据类型,也不需要根据在q行期才定的类型名U创建其对象?/p> <p>动态创建就是创建某U类型的对象Q具体类型在q行时确定,~译时可能不知道。比如运行时用户输入一个类型名Uͼ如果该类型是E序cd体系中的一员,则程序中能够创cd的对象。下面的代码是用MFC动态创建机制的一个简化的例子Q?/p> <p>CRuntimeClass* g_pFirstClass;<br>void func()<br>{<br>     char szClassName[64];<br>     CRuntimeClass* pClass;<br>     CObject* pObject;<br>     <br>     cout << "enter a class name...  ";<br>     cin >> szClassName;<br>     <br>     for (pClass = g_pFirstClass; pClass != NULL; pClass = pClass->m_pNextClass)<br>     {<br>          if (strcmp(szClassName, pClass->m_lpszClassName) == 0)<br>              pObject = pClass->CreateObject();<br>     }<br>}</p> <p>实现动态创建的思\是把动态的cd名称与程序类型体pM的每一个进行比较,与某个类型吻合时让该cd创徏自n的对象。这P支持动态创建的cd中的每一个类都要额外实现一些功能,卛_别一个名U是否与自n相符Q以及创w的对象?/p> <p>判别一个名U是否与自n相符Q这是运行时c识别的内容Q所以MFC动态创建是在RTCI基础上实现的?/p> <p>RTCI是一个对象能够判定自己是否属于某U类型,该类型的名称在运行时定Q编译时可能不知道。从下面的例子很Ҏ理解RTCIQ?/p> <p>void Func()<br>{<br>     char szClassName[64];<br>     CDocument* pDoc = new CDocument;<br>     <br>     cout << "enter a class name...  ";<br>     cin >> szClassName;<br>     <br>     cout << pDoc->IsKindOf(szClassName); //是返?Q否q回0<br>}</p> <p>有一炚w要说明的是,因ؓCDocumentz于CObjectQ所以IsKindOf对于CObject也要q回1。因为我们是从动态创建出发的Q所以如果是q样可能会有一点背d街但是RTCI明显和动态创建有密切联系QRTCI也可能有单独的h|所以先把RTCI实现h?/p> <p>实现RTCI的思\是让每一个类记录自n的类型信息,q提供IsKindOf(char*)函数q行所l类型与自ncd的比较,而且q要能访问基cȝcd信息Q进行比较,一直到根类。所以记录的cd信息要按l承关系qv来,每个cȝIsKindOf()q要调用基类的IsKindOf()。MFC把要记录的类型信息抽取到一个CRuntimeClassl构体中Q每个类中加入一个CRuntimeClass成员卛_?/p> <p>现在回到动态创建,在RTCI建立的数据结构基上将可实现它。动态创Z不同于IsKindOf()的角度用这一数据l构Q它要遍历所有类型的CRuntimeClass。那么仅仅有l承关系的类的CRuntimeClass相连q不够,要把所有类的CRuntimeClassq成一个链表。其实动态创建ƈ不关心类间的l承关系Q它q等看待每个cR现在以CRuntimeClass为结Ҏ成一个纵横两个方向的链表QIsKindOf()和动态创建分别用它不同的侧面?/p> <p>序列化的概念是在文g中存储对象信息,q能Ҏ它恢复对象。对于文档视囄构的软gQ用户需要保存所~辑的文档和打开已编辑的文档Q这正是序列化的应用Q所以序列化是非帔R要的一U特性。在序列化恢复对象时Q就可以用到动态创建?/p> <p>使用MFC序列化的例子如下Q?/p> <p>void CMyDocument::Serialize(CArichive &ar)<br>{<br>    if (ar.IsStoring())<br>    {<br>        ar << m_pMyClass; //CMyClass m_pMyClass;<br>    }<br>    else<br>    {<br>        ar >> m_pMyClass;<br>    }<br>}</p> <p>一个支持序列化的类提供Serialize(CArchive &)函数Q重?lt;<?gt;>操作。注意两者是不同的,在上例中QCMyDocumentcȝ信息q不被序列化Q而CMyClasscȝ信息被序列化。实际上一个序列化cȝ<<?gt;>操作Q其不涉及类信息的部分是调用Serialize()完成的,它必d时实现这两者?/p> <p>按照MFC的要求,需要在支持序列化的cd义中使用DECLARE_SERIAL宏,在类实现中用IMPLEMENT_SERIAL宏。我们看一下这两个宏实C什么,</p> <p>#define DECLARE_SERIAL(class_name) \<br> _DECLARE_DYNCREATE(class_name) \<br> AFX_API friend CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb);</p> <p>#define IMPLEMENT_SERIAL(class_name, base_class_name, wSchema) \<br> CObject* PASCAL class_name::CreateObject() \<br>  { return new class_name; } \<br> _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, \<br>  class_name::CreateObject) \<br> AFX_CLASSINIT _init_##class_name(RUNTIME_CLASS(class_name)); \<br> CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb) \<br>  { pOb = (class_name*) ar.ReadObject(RUNTIME_CLASS(class_name)); \<br>   return ar; } \</p> <p>主要是加入了?gt;>的重载,但是没有重蝲<<QMFC仅提供了CObject?lt;<的重载,如下Q?/p> <p>_AFX_INLINE CArchive& AFXAPI operator<<(CArchive& ar, const CObject* pOb)<br> { ar.WriteObject(pOb); return ar; }</p> <p>q是因ؓ在序列化d写的时候,都需要具体类的CRuntimeClass信息。相应的GetRuntimeClass()是一个虚函数QCObject重蝲<<Q在写类信息时调用到该函敎ͼ׃虚函数机Ӟ写入的是具体cȝ信息。但是这里隐含着一个条Ӟ是调用<<和GetRuntimeClass()Ӟ具体cd象已l存在了Q而调?gt;>和读入类信息Ӟ该类对象q未被创建,所以无法利用这U机Ӟ只能在每个具体类中都重蝲一?gt;>。我觉得《深入解析MFC》对q个问题的解释不正确?/p> <p>q里有一个问题需要明一下,序列化ؓ什么要写入cM息?一是它应该保存完整的能够独立恢复对象的信息Q二是在E序d对象Ӟ要把它的cM息和E序中期望的(所能处理的)cM息相比较Q进行检验?/p> <p>看IMPLEMENT_SERIAL宏对重蝲>>的实玎ͼ是提供一个期望的CRuntimeClassl构(用于?Q委托CArchiveq行对象d。因对象旉先要跟文件打交道Q所以交lCArchive处理Q随后把d的数据写入对象时QCArchive再调用具体类的Serialize()Q如此合作是十分恰当的。在q里QCArchiveq负责了d和检验类信息Q然后创建对象的q程。因Z斚w具体cd象还不存在,另一斚wq些操作Ҏ有具体类都没有分别,应该提出来,在类U别实现或者让合作者实现。实际上QMFC先把q个q程交给CArchive::ReadClass()Q后者又调用CRuntimeClass::Load()?nbsp;</p> <p>对于序列化来_搞清它的概念以后Q就是实现Serialzie()Q重?lt;<?gt;>。对<<?gt;>的重载涉及很多工作,MFC已经帮我们实CQ我们也看见了大概的设计Q主要是与CArchive分工合作Q其ơ是CRuntimeClass?/p> <p>现在看到CRuntimeClassl构体在MFC对RTCIQ动态创建和序列化的实现中都L重要的作用,重新认识一下这个数据结构很有必要?/p> <p>CRuntimeClass包含了关于类的各U信息和有关操作。把cd其基cȝCRuntimeClassq成一个链表,可以很方便地实现RTCI的IsKindOf()Q把所有类的CRuntimeClassq成一个链表,再加上一个简单的CreateObject函数Q就可以对以Lcdq行动态创建的企图做出反应QCRuntimeClassq实C向文件读写类信息的Load()QStore()Q配合序列化的实现?/p> <p>在分析消息映和命o传递机制之前,需要对<a title=WindowsE序模型 href="http://www.shnenglu.com/zliner/archive/2007/04/15/21942.html">WindowsE序模型</a>有很好的理解?/p> <p>未完待箋...<br><br><br>参考:<br><br>《深入解析MFC?中国电力出版C?br>《深入浅出MFC?华中U大出版C?br>《WindowsE序设计?北大出版C?/p> <img src ="http://www.shnenglu.com/zliner/aggbug/7218.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/zliner/" target="_blank">依旧的博?/a> 2006-05-15 19:33 <a href="http://www.shnenglu.com/zliner/archive/2006/05/15/7218.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>思\ƣ赏http://www.shnenglu.com/zliner/archive/2006/05/12/7045.html依旧的博?/dc:creator>依旧的博?/author>Fri, 12 May 2006 15:14:00 GMThttp://www.shnenglu.com/zliner/archive/2006/05/12/7045.htmlhttp://www.shnenglu.com/zliner/comments/7045.htmlhttp://www.shnenglu.com/zliner/archive/2006/05/12/7045.html#Feedback2http://www.shnenglu.com/zliner/comments/commentRss/7045.htmlhttp://www.shnenglu.com/zliner/services/trackbacks/7045.html
1. 问题Q对32位的二进制整敎ͼ不用循环Q求出其?的个数?br />
#define POW(c) (1<<(c))
#define MASK(c) (((unsigned long)-1) / (POW(POW(c)) + 1))
#define ROUND(n, c) (((n) & MASK(c)) + ((n) >> POW(c) & MASK(c)))

int bit_count(unsigned int n)
{
    n 
= ROUND(n, 0);
    n 
= ROUND(n, 1);
    n 
= ROUND(n, 2);
    n 
= ROUND(n, 3);
    n 
= ROUND(n, 4);
    
return n;
}

基本的想法是把所有的1加v来,得到的就?的个数。我们需要把q些1分离出来Q每?都是q等的,与其位置无关。难题在于不能一个一个去取,那就用到了@环,当然递归也是不允许的。需要有一U统一的办法,可是很难惌具体该怎样。我们逐步地做qg事,假设?6位和?6位分别求得了1的个敎ͼ那么加v来就行了?6位二q制中的1仍然是未知的Q随机出现的Q问题的性质没有变,但我们可以l分解,q种逐步的做法不一定就意味着递归。每?6位分解ؓ两个8位,...,每个2位分解ؓ两个1位,把两?位上的数相加是q两位上1的个数。现在需要取出每一位上的数吗?如果惛_了这个问题,q最l的思\不远了。现?2位已l分成了16个两位,很容易将其看作两?6位,一个是所有奇CQ一个是所有偶C。我们不难把q两?6位分开Q然后移位相加,求Z每两位中1的个数。到了这一步,以后的思\很自然了?br />

参考:

《计二q制?1'的个数》来自?a >http://kaikai.cnblogs.com

]]>
þþĻ| ɫþþ99Ʒ91| þƵһ| ŷƷž99þڹۿ| ۺҹҹþ| ھƷþþþþ99| 99ȶǾƷþþþþ| 鶹Ʒþþþþþ99| ŮþþƷ㽶69| þݺҹҹav˳| þþƷav鶹ͼƬ| 99ƷȾþ| ۺϾþøϾþúݺݺ97ɫ| 72ŷþþþôƽ| ޹˾þһҳ| 97Ʒþ찴Ħ| ޾ƷۺϾþ| 99þһ| ɫþþþþþС˵| Ʒ91þþþþþa| þþһƷ99þþƷ66| þˬˬƬAV| ޾Ʒھþ| ˾ƷǾþ| ëƬþþþþùëƬ| 91ƷۺϾþþƷ| þˬˬƬAV| Ʒþþþþҹҹ| ھƷþþþþ99| þˬˬAV| þþþþþòҰ¸߳| þоƷƵ| ŷþ޾Ʒ| ƷþþĻһ| ŷ þ| ɫۺϺϾþۺӿ| ֻоƷþ| ĻѾþ| 777þþƷһ | ۺþþ| þþþþùƷ볬|