﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-C++编程失乐园</title><link>http://www.cppblog.com/mumutou/</link><description>致力于解决论坛的不足,探讨C++的原理</description><language>zh-cn</language><lastBuildDate>Sun, 19 Apr 2026 12:18:01 GMT</lastBuildDate><pubDate>Sun, 19 Apr 2026 12:18:01 GMT</pubDate><ttl>60</ttl><item><title>UML随笔 之 类图描述</title><link>http://www.cppblog.com/mumutou/archive/2007/01/21/17856.html</link><dc:creator>木木头</dc:creator><author>木木头</author><pubDate>Sun, 21 Jan 2007 04:36:00 GMT</pubDate><guid>http://www.cppblog.com/mumutou/archive/2007/01/21/17856.html</guid><wfw:comment>http://www.cppblog.com/mumutou/comments/17856.html</wfw:comment><comments>http://www.cppblog.com/mumutou/archive/2007/01/21/17856.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mumutou/comments/commentRss/17856.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mumutou/services/trackbacks/17856.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: A.        																类图																																																																														类																																																	...&nbsp;&nbsp;<a href='http://www.cppblog.com/mumutou/archive/2007/01/21/17856.html'>阅读全文</a><img src ="http://www.cppblog.com/mumutou/aggbug/17856.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mumutou/" target="_blank">木木头</a> 2007-01-21 12:36 <a href="http://www.cppblog.com/mumutou/archive/2007/01/21/17856.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>UML随笔 之 Rose对VC的正向 反向工程</title><link>http://www.cppblog.com/mumutou/archive/2007/01/21/17855.html</link><dc:creator>木木头</dc:creator><author>木木头</author><pubDate>Sun, 21 Jan 2007 04:35:00 GMT</pubDate><guid>http://www.cppblog.com/mumutou/archive/2007/01/21/17855.html</guid><wfw:comment>http://www.cppblog.com/mumutou/comments/17855.html</wfw:comment><comments>http://www.cppblog.com/mumutou/archive/2007/01/21/17855.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/mumutou/comments/commentRss/17855.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mumutou/services/trackbacks/17855.html</trackback:ping><description><![CDATA[
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="2">
						<font face="Courier New">
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用</span>
								<span lang="EN-US">[IBM</span>
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">软件系列</span>
								<span lang="EN-US">].IBM.Rational.Rose.Enterprise.v7.0-TFTISO</span>
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">建立镜像后安装</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="2">
						<font face="Courier New">
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">打开</span>
								<span lang="EN-US">Rose</span>
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">软件</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="2">
						<font face="Courier New">
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">由于本人经常使用</span>
								<span lang="EN-US">VC6.0</span>
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">开发软件</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font face="Courier New" size="2">首先来谈谈</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="2">
						<font face="Courier New">
								<span lang="EN-US">Rose</span>
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">关于</span>
								<span lang="EN-US">VC6.0</span>
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的正向和逆向工程吧</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /?>
						<v:shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600">
								<font size="2">
										<font face="Courier New">
												<v:stroke joinstyle="miter">
												</v:stroke>
												<v:formulas>
														<v:f eqn="if lineDrawn pixelLineWidth 0">
														</v:f>
														<v:f eqn="sum @0 1 0">
														</v:f>
														<v:f eqn="sum 0 0 @1">
														</v:f>
														<v:f eqn="prod @2 1 2">
														</v:f>
														<v:f eqn="prod @3 21600 pixelWidth">
														</v:f>
														<v:f eqn="prod @3 21600 pixelHeight">
														</v:f>
														<v:f eqn="sum @0 0 1">
														</v:f>
														<v:f eqn="prod @6 1 2">
														</v:f>
														<v:f eqn="prod @7 21600 pixelWidth">
														</v:f>
														<v:f eqn="sum @8 21600 0">
														</v:f>
														<v:f eqn="prod @7 21600 pixelHeight">
														</v:f>
														<v:f eqn="sum @10 21600 0">
														</v:f>
												</v:formulas>
												<v:path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f">
												</v:path>
												<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?>
												<o:lock aspectratio="t" v:ext="edit">
												</o:lock>
										</font>
								</font>
						</v:shapetype>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="2">
						<font face="Courier New">
								<span lang="EN-US">Rose</span>
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">总共有</span>
								<span lang="EN-US">5</span>
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">种类型图</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt">
				<font size="2">
						<font face="Courier New">
								<span lang="EN-US" style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings">
										<span style="mso-list: Ignore">²<span style="FONT: 7pt 'Times New Roman'">        </span></span>
								</span>
								<span lang="EN-US">Use Case View</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt">
				<font size="2">
						<font face="Courier New">
								<span lang="EN-US" style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings">
										<span style="mso-list: Ignore">²<span style="FONT: 7pt 'Times New Roman'">        </span></span>
								</span>
								<span lang="EN-US">Logical View</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt">
				<font size="2">
						<font face="Courier New">
								<span lang="EN-US" style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings">
										<span style="mso-list: Ignore">²<span style="FONT: 7pt 'Times New Roman'">        </span></span>
								</span>
								<span lang="EN-US">Component View</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt">
				<font size="2">
						<font face="Courier New">
								<span lang="EN-US" style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings">
										<span style="mso-list: Ignore">²<span style="FONT: 7pt 'Times New Roman'">        </span></span>
								</span>
								<span lang="EN-US">Deployment View</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt">
				<font size="2">
						<font face="Courier New">
								<span lang="EN-US" style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings">
										<span style="mso-list: Ignore">²<span style="FONT: 7pt 'Times New Roman'">        </span></span>
								</span>
								<span lang="EN-US">Model Properties</span>
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">其实并不能说是一种图</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<o:p>
								<font face="Courier New" size="2"> </font>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="2">
						<font face="Courier New">
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">现在我们先来谈谈</span>
								<span lang="EN-US">Logical View</span>
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就是静态图，</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font face="Courier New" size="2">经常我们使用它来做一些静态类库。</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font face="Courier New" size="2">好了，先来看看反向工程吧</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<font face="Courier New" size="2">[tools]-&gt;[Visual C++]-&gt;[Update Model From Code]</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="2">
						<font face="Courier New">
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">出现</span>
								<span lang="EN-US">Model Update Tool-Select Components and Classes</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="2">
						<font face="Courier New">
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果在</span>
								<span lang="EN-US">VC++</span>
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">下面没有项的话，点击</span>
								<span lang="EN-US">Add Component,</span>
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">添加一个要施行逆向工程的</span>
								<span lang="EN-US">VC</span>
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">工程</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="2">
						<font face="Courier New">
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">点击工程下面所有的类，点击</span>
								<span lang="EN-US">Next</span>
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就可以了。</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<o:p>
								<font face="Courier New" size="2"> </font>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<o:p>
								<font face="Courier New" size="2"> </font>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font face="Courier New" size="2">我们再来看看正向工程</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<font face="Courier New" size="2">[tools]-&gt;[Visual C++]-&gt;[Update Code]</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font face="Courier New" size="2">同样安装以上操作就可以了</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<o:p>
								<font face="Courier New" size="2"> </font>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font face="Courier New" size="2">如果我们添加一个类的话，那么就必须要使用</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="2">
						<font face="Courier New">
								<span lang="EN-US">[Tools]-&gt;[Visual C++]-&gt;[Component Assignment Tool]</span>
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来把添加的类包含到实行正向工程的</span>
								<span lang="EN-US">VC</span>
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">工程里面。</span>
						</font>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<o:p>
								<font face="Courier New" size="2"> </font>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<o:p>
								<font face="Courier New" size="2"> </font>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<o:p>
								<font face="Courier New" size="2"> </font>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<o:p>
								<font face="Courier New" size="2"> </font>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<o:p>
								<font face="Courier New" size="2"> </font>
						</o:p>
				</span>
		</p>
<img src ="http://www.cppblog.com/mumutou/aggbug/17855.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mumutou/" target="_blank">木木头</a> 2007-01-21 12:35 <a href="http://www.cppblog.com/mumutou/archive/2007/01/21/17855.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>UML随笔 之 类 关系</title><link>http://www.cppblog.com/mumutou/archive/2007/01/19/17776.html</link><dc:creator>木木头</dc:creator><author>木木头</author><pubDate>Fri, 19 Jan 2007 04:04:00 GMT</pubDate><guid>http://www.cppblog.com/mumutou/archive/2007/01/19/17776.html</guid><wfw:comment>http://www.cppblog.com/mumutou/comments/17776.html</wfw:comment><comments>http://www.cppblog.com/mumutou/archive/2007/01/19/17776.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mumutou/comments/commentRss/17776.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mumutou/services/trackbacks/17776.html</trackback:ping><description><![CDATA[
		<font face="Courier New" size="2">类关系总共分为<br /><font color="#0000ff">1.继承关系[一般化关系]<br /></font>class A{};<br />class B:public A<br />{};<br />A和B是继承关系<br /><font color="#0000ff">2.关联关系</font><br />class A{};<br />class B<br />{<br />   void   Function1(A *a);<br />}<br />A和B是关联关系<br /><font color="#0000ff">3.聚合关系</font><br />class A{};<br />class B<br />{<br />   A *a;<br />};<br />A和B是聚合关系<br />比如XX市这个类<br />class XX市<br />{<br />   劳动局   *劳动局1;<br />   供电局 *供电局1;<br />   粮食局 *粮食局1;<br />};<br /><font color="#0000ff">4.组合关系</font><br />class A{};<br />class B<br />{<br />   A a;<br />};<br />A和B是组合关系<br /><br />组合关系和聚合关系比起来，其强度要高一点；<br /></font>
<img src ="http://www.cppblog.com/mumutou/aggbug/17776.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mumutou/" target="_blank">木木头</a> 2007-01-19 12:04 <a href="http://www.cppblog.com/mumutou/archive/2007/01/19/17776.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++随笔 之 C++风格的类型转换的用法 (转载)</title><link>http://www.cppblog.com/mumutou/archive/2007/01/16/17682.html</link><dc:creator>木木头</dc:creator><author>木木头</author><pubDate>Tue, 16 Jan 2007 05:24:00 GMT</pubDate><guid>http://www.cppblog.com/mumutou/archive/2007/01/16/17682.html</guid><wfw:comment>http://www.cppblog.com/mumutou/comments/17682.html</wfw:comment><comments>http://www.cppblog.com/mumutou/archive/2007/01/16/17682.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mumutou/comments/commentRss/17682.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mumutou/services/trackbacks/17682.html</trackback:ping><description><![CDATA[
		<div class="postbody">
				<font face="Courier New" size="2">C++风格的类型转换的用法 </font>
				<p>
						<font face="Courier New" size="2">这是More Effecitve C++里的第二条对类型转换讲的很好，也很基础好懂。<br />Item M2：尽量使用C++风格的类型转换<br />仔细想想地位卑贱的类型转换功能（cast），其在程序设计中的地位就象goto语句一样令人鄙视。但是它还不是无法令人忍受，因为当在某些紧要的关头，类型转换还是必需的，这时它是一个必需品。<br />不过C风格的类型转换并不代表所有的类型转换功能。<br />一来它们过于粗鲁，能允许你在任何类型之间进行转换。不过如果要进行更精确的类型转换，这会是一个优点。在这些类型转换中存在着巨大的不同，例如把一个指向 const对象的指针（pointer-to-const-object）转换成指向非const对象的指针（pointer-to-non-const -object）(即一个仅仅去除const的类型转换)，把一个指向基类的指针转换成指向子类的指针（即完全改变对象类型）。传统的C风格的类型转换不对上述两种转换进行区分。（这一点也不令人惊讶，因为C风格的类型转换是为C语言设计的，而不是为C++语言设计的）。<br />二来C风格的类型转换在程序语句中难以识别。在语法上，类型转换由圆括号和标识符组成，而这些可以用在C＋＋中的任何地方。这使得回答象这样一个最基本的有关类型转换的问题变得很困难：“在这个程序中是否使用了类型转换？”。这是因为人工阅读很可能忽略了类型转换的语句，而利用象grep的工具程序也不能从语句构成上区分出它们来。<br />C++通过引进四个新的类型转换操作符克服了C风格类型转换的缺点，这四个操作符是, static_cast, const_cast, dynamic_cast, 和reinterpret_cast。在大多数情况下，对于这些操作符你只需要知道原来你习惯于这样写，<br />(type) expression<br />而现在你总应该这样写：<br />static_cast&lt;type&gt;(expression)<br />例如，假设你想把一个int转换成double，以便让包含int类型变量的表达式产生出浮点数值的结果。如果用C风格的类型转换，你能这样写：<br />int firstNumber, secondNumber;<br />...<br />double result = ((double)firstNumber)/secondNumber；<br />如果用上述新的类型转换方法，你应该这样写：<br />double result = static_cast&lt;double&gt;(firstNumber)/secondNumber;<br />这样的类型转换不论是对人工还是对程序都很容易识别。<br />static_cast 在功能上基本上与C风格的类型转换一样强大，含义也一样。它也有功能上限制。例如，你不能用static_cast象用C风格的类型转换一样把 struct转换成int类型或者把double类型转换成指针类型，另外，static_cast不能从表达式中去除const属性，因为另一个新的类型转换操作符const_cast有这样的功能。<br />其它新的C++类型转换操作符被用在需要更多限制的地方。const_cast用于类型转换掉表达式的const或volatileness属性。通过使用const_cast，你向人们和编译器强调你通过类型转换想做的只是改变一些东西的 constness或者volatileness属性。这个含义被编译器所约束。如果你试图使用const_cast来完成修改constness 或者volatileness属性之外的事情，你的类型转换将被拒绝。下面是一些例子：<br />class Widget { ... };<br />class SpecialWidget: public Widget { ... };<br />void update(SpecialWidget *psw);<br />SpecialWidget sw; // sw 是一个非const 对象。<br />const SpecialWidget&amp; csw = sw; // csw 是sw的一个引用<br />// 它是一个const 对象<br />update(&amp;csw); // 错误!不能传递一个const SpecialWidget* 变量<br />// 给一个处理SpecialWidget*类型变量的函数<br />update(const_cast&lt;SpecialWidget*&gt;(&amp;csw));<br />// 正确，csw的const被显示地转换掉（<br />// csw和sw两个变量值在update<br />//函数中能被更新）<br />update((SpecialWidget*)&amp;csw);<br />// 同上，但用了一个更难识别<br />//的C风格的类型转换<br />Widget *pw = new SpecialWidget;<br />update(pw); // 错误！pw的类型是Widget*，但是<br />// update函数处理的是SpecialWidget*类型<br />update(const_cast&lt;SpecialWidget*&gt;(pw));<br />// 错误！const_cast仅能被用在影响<br />// constness or volatileness的地方上。,<br />// 不能用在向继承子类进行类型转换。<br />到目前为止，const_cast最普通的用途就是转换掉对象的const属性。<br />第二种特殊的类型转换符是dynamic_cast，它被用于安全地沿着类的继承关系向下进行类型转换。这就是说，你能用dynamic_cast把指向基类的指针或引用转换成指向其派生类或其兄弟类的指针或引用，而且你能知道转换是否成功。失败的转换将返回空指针（当对指针进行类型转换时）或者抛出异常（当对引用进行类型转换时）：<br />Widget *pw;<br />...<br />update(dynamic_cast&lt;SpecialWidget*&gt;(pw));<br />// 正确，传递给update函数一个指针<br />// 是指向变量类型为SpecialWidget的pw的指针<br />// 如果pw确实指向一个对象,<br />// 否则传递过去的将使空指针。<br />void updateViaRef(SpecialWidget&amp; rsw);<br />updateViaRef(dynamic_cast&lt;SpecialWidget&amp;&gt;(*pw));<br />//正确。传递给updateViaRef函数<br />// SpecialWidget pw 指针，如果pw<br />// 确实指向了某个对象<br />// 否则将抛出异常<br />dynamic_casts在帮助你浏览继承层次上是有限制的。它不能被用于缺乏虚函数的类型上（参见条款M24），也不能用它来转换掉constness：<br />int firstNumber, secondNumber;<br />...<br />double result = dynamic_cast&lt;double&gt;(firstNumber)/secondNumber;<br />// 错误！没有继承关系<br />const SpecialWidget sw;<br />...<br />update(dynamic_cast&lt;SpecialWidget*&gt;(&amp;sw));<br />// 错误! dynamic_cast不能转换<br />// 掉const。<br />如你想在没有继承关系的类型中进行转换，你可能想到static_cast。如果是为了去除const，你总得用const_cast。<br />这四个类型转换符中的最后一个是reinterpret_cast。使用这个操作符的类型转换，其的转换结果几乎都是执行期定义（implementation-defined）。因此，使用reinterpret_casts的代码很难移植。<br />reinterpret_casts的最普通的用途就是在函数指针类型之间进行转换。例如，假设你有一个函数指针数组：<br />typedef void (*FuncPtr)(); // FuncPtr is 一个指向函数<br />// 的指针，该函数没有参数<br />// 返回值类型为void<br />FuncPtr funcPtrArray[10]; // funcPtrArray 是一个能容纳<br />// 10个FuncPtrs指针的数组<br />让我们假设你希望（因为某些莫名其妙的原因）把一个指向下面函数的指针存入funcPtrArray数组：<br />int doSomething();<br />你不能不经过类型转换而直接去做，因为doSomething函数对于funcPtrArray数组来说有一个错误的类型。在FuncPtrArray数组里的函数返回值是void类型，而doSomething函数返回值是int类型。<br />funcPtrArray[0] = &amp;doSomething; // 错误！类型不匹配<br />reinterpret_cast可以让你迫使编译器以你的方法去看待它们：<br />funcPtrArray[0] = // this compiles<br />reinterpret_cast&lt;FuncPtr&gt;(&amp;doSomething);<br />转换函数指针的代码是不可移植的（C++不保证所有的函数指针都被用一样的方法表示），在一些情况下这样的转换会产生不正确的结果（参见条款M31），所以你应该避免转换函数指针类型，除非你处于着背水一战和尖刀架喉的危急时刻。一把锋利的刀。一把非常锋利的刀。<br />如果你使用的编译器缺乏对新的类型转换方式的支持，你可以用传统的类型转换方法代替static_cast, const_cast, 以及reinterpret_cast。也可以用下面的宏替换来模拟新的类型转换语法：<br />#define static_cast(TYPE,EXPR) ((TYPE)(EXPR))<br />#define const_cast(TYPE,EXPR) ((TYPE)(EXPR))<br />#define reinterpret_cast(TYPE,EXPR) ((TYPE)(EXPR))<br />你可以象这样使用使用：<br />double result = static_cast(double, firstNumber)/secondNumber;<br />update(const_cast(SpecialWidget*, &amp;sw));<br />funcPtrArray[0] = reinterpret_cast(FuncPtr, &amp;doSomething);<br />这些模拟不会象真实的操作符一样安全，但是当你的编译器可以支持新的的类型转换时，它们可以简化你把代码升级的过程。<br />没有一个容易的方法来模拟dynamic_cast的操作，但是很多函数库提供了函数，安全地在派生类与基类之间进行类型转换。如果你没有这些函数而你有必须进行这样的类型转换，你也可以回到C风格的类型转换方法上，但是这样的话你将不能获知类型转换是否失败。当然，你也可以定义一个宏来模拟 dynamic_cast的功能，就象模拟其它的类型转换一样：<br />#define dynamic_cast(TYPE,EXPR) (TYPE)(EXPR)<br />请记住，这个模拟并不能完全实现dynamic_cast的功能，它没有办法知道转换是否失败。<br />我知道，是的，我知道，新的类型转换操作符不是很美观而且用键盘键入也很麻烦。如果你发现它们看上去实在令人讨厌，C风格的类型转换还可以继续使用并且合法。然而，正是因为新的类型转换符缺乏美感才能使它弥补了在含义精确性和可辨认性上的缺点。并且，使用新类型转换符的程序更容易被解析（不论是对人工还是对于工具程序），它们允许编译器检测出原来不能发现的错误。这些都是放弃C风格类型转换方法的强有力的理由。还有第三个理由：也许让类型转换符不美观和键入麻烦是一件好事。 </font>
				</p>
		</div>
<img src ="http://www.cppblog.com/mumutou/aggbug/17682.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mumutou/" target="_blank">木木头</a> 2007-01-16 13:24 <a href="http://www.cppblog.com/mumutou/archive/2007/01/16/17682.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++随笔 之 explicit 关键字(转载)</title><link>http://www.cppblog.com/mumutou/archive/2007/01/16/17681.html</link><dc:creator>木木头</dc:creator><author>木木头</author><pubDate>Tue, 16 Jan 2007 05:21:00 GMT</pubDate><guid>http://www.cppblog.com/mumutou/archive/2007/01/16/17681.html</guid><wfw:comment>http://www.cppblog.com/mumutou/comments/17681.html</wfw:comment><comments>http://www.cppblog.com/mumutou/archive/2007/01/16/17681.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mumutou/comments/commentRss/17681.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mumutou/services/trackbacks/17681.html</trackback:ping><description><![CDATA[
		<font face="Courier New" size="2">explicit关键字用于取消构造函数的隐式转换，对有多个参数的构造函数使用explicit是个语法错误。<br /></font>
		<p>
				<br />
		</p>
		<p>
				<font face="Courier New" size="2">In C++ it is possible to declare constructors for a class, taking a single parameter, and use those constructors for doing type conversion. For example: <br /></font>
		</p>
		<pre>
				<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)">
						<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
						<span style="COLOR: rgb(0,0,0)">
						</span>
						<span style="COLOR: rgb(0,0,255)">
								<font size="2">class</font>
						</span>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)"> A {<br /></span>
								<span style="COLOR: rgb(0,0,255)">public</span>
						</font>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)">:<br />        A(</span>
								<span style="COLOR: rgb(0,0,255)">int</span>
						</font>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)">);<br />};<br /><br /></span>
								<span style="COLOR: rgb(0,0,255)">void</span>
						</font>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)"> f(A) {}<br /></span>
								<span style="COLOR: rgb(0,0,255)">void</span>
						</font>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)"> g()<br />{<br />         A a1 </span>
								<span style="COLOR: rgb(0,0,0)">=</span>
								<span style="COLOR: rgb(0,0,0)"> </span>
								<span style="COLOR: rgb(0,0,0)">37</span>
						</font>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)">;<br />         A a2 </span>
								<span style="COLOR: rgb(0,0,0)">=</span>
								<span style="COLOR: rgb(0,0,0)"> A(</span>
								<span style="COLOR: rgb(0,0,0)">47</span>
						</font>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)">);<br />         A a3(</span>
								<span style="COLOR: rgb(0,0,0)">57</span>
						</font>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)">);<br />         a1 </span>
								<span style="COLOR: rgb(0,0,0)">=</span>
								<span style="COLOR: rgb(0,0,0)"> </span>
								<span style="COLOR: rgb(0,0,0)">67</span>
						</font>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)">;<br />         f(</span>
								<span style="COLOR: rgb(0,0,0)">77</span>
						</font>
						<span style="COLOR: rgb(0,0,0)">
								<font size="2">);<br />}<br /></font>
						</span>
				</div>
				<br />
				<font size="2">A declaration like:<br />	 A a1 = 37;<br />says to call the A(int) constructor to create an A object from
the integer value. Such a constructor is called a "converting
constructor". <br /></font>
		</pre>
		<p>
				<font face="Courier New" size="2">However, this type of implicit conversion can be confusing, and there is a way of disabling it, using a new keyword "explicit" in the constructor declaration: <br /></font>
		</p>
		<pre>
				<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)">
						<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
						<span style="COLOR: rgb(0,0,0)">
						</span>
						<span style="COLOR: rgb(0,0,255)">
								<font size="2">class</font>
						</span>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)"> A {<br /></span>
								<span style="COLOR: rgb(0,0,255)">public</span>
						</font>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)">:<br />        </span>
								<span style="COLOR: rgb(0,0,255)">explicit</span>
								<span style="COLOR: rgb(0,0,0)"> A(</span>
								<span style="COLOR: rgb(0,0,255)">int</span>
						</font>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)">);<br />};<br /><br /></span>
								<span style="COLOR: rgb(0,0,255)">void</span>
						</font>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)"> f(A) {}<br /></span>
								<span style="COLOR: rgb(0,0,255)">void</span>
						</font>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)"> g()<br />{<br />          A a1 </span>
								<span style="COLOR: rgb(0,0,0)">=</span>
								<span style="COLOR: rgb(0,0,0)"> </span>
								<span style="COLOR: rgb(0,0,0)">37</span>
								<span style="COLOR: rgb(0,0,0)">;      </span>
								<span style="COLOR: rgb(0,128,0)">//</span>
								<span style="COLOR: rgb(0,128,0)"> illegal</span>
						</font>
						<span style="COLOR: rgb(0,128,0)">
								<br />
						</span>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)">          A a2 </span>
								<span style="COLOR: rgb(0,0,0)">=</span>
								<span style="COLOR: rgb(0,0,0)"> A(</span>
								<span style="COLOR: rgb(0,0,0)">47</span>
								<span style="COLOR: rgb(0,0,0)">);   </span>
								<span style="COLOR: rgb(0,128,0)">//</span>
								<span style="COLOR: rgb(0,128,0)"> OK</span>
						</font>
						<span style="COLOR: rgb(0,128,0)">
								<br />
						</span>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)">          A a3(</span>
								<span style="COLOR: rgb(0,0,0)">57</span>
								<span style="COLOR: rgb(0,0,0)">);       </span>
								<span style="COLOR: rgb(0,128,0)">//</span>
								<span style="COLOR: rgb(0,128,0)"> OK</span>
						</font>
						<span style="COLOR: rgb(0,128,0)">
								<br />
						</span>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)">          a1 </span>
								<span style="COLOR: rgb(0,0,0)">=</span>
								<span style="COLOR: rgb(0,0,0)"> </span>
								<span style="COLOR: rgb(0,0,0)">67</span>
								<span style="COLOR: rgb(0,0,0)">;        </span>
								<span style="COLOR: rgb(0,128,0)">//</span>
								<span style="COLOR: rgb(0,128,0)"> illegal</span>
						</font>
						<span style="COLOR: rgb(0,128,0)">
								<br />
						</span>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)">          f(</span>
								<span style="COLOR: rgb(0,0,0)">77</span>
								<span style="COLOR: rgb(0,0,0)">);          </span>
								<span style="COLOR: rgb(0,128,0)">//</span>
								<span style="COLOR: rgb(0,128,0)"> illegal</span>
						</font>
						<span style="COLOR: rgb(0,128,0)">
								<br />
						</span>
						<span style="COLOR: rgb(0,0,0)">
								<font size="2">}<br /><br /></font>
						</span>
				</div>
				<br />
		</pre>
		<font face="Courier New" size="2">Using the explicit keyword, a constructor is declared to be<br />"nonconverting", and explicit constructor syntax is required:<br /><br /></font>
		<pre>
				<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)">
						<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
						<span style="COLOR: rgb(0,0,255)">
								<font size="2">class</font>
						</span>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)"> A {<br /></span>
								<span style="COLOR: rgb(0,0,255)">public</span>
						</font>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)">:<br />        </span>
								<span style="COLOR: rgb(0,0,255)">explicit</span>
								<span style="COLOR: rgb(0,0,0)"> A(</span>
								<span style="COLOR: rgb(0,0,255)">int</span>
						</font>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)">);<br />        };<br /><br /></span>
								<span style="COLOR: rgb(0,0,255)">void</span>
						</font>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)"> f(A) {}<br /><br /></span>
								<span style="COLOR: rgb(0,0,255)">void</span>
						</font>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)"> g()<br />{<br />        A a1 </span>
								<span style="COLOR: rgb(0,0,0)">=</span>
								<span style="COLOR: rgb(0,0,0)"> A(</span>
								<span style="COLOR: rgb(0,0,0)">37</span>
						</font>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)">);<br />        A a2 </span>
								<span style="COLOR: rgb(0,0,0)">=</span>
								<span style="COLOR: rgb(0,0,0)"> A(</span>
								<span style="COLOR: rgb(0,0,0)">47</span>
						</font>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)">);<br />        A a3(</span>
								<span style="COLOR: rgb(0,0,0)">57</span>
						</font>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)">);<br />        a1 </span>
								<span style="COLOR: rgb(0,0,0)">=</span>
								<span style="COLOR: rgb(0,0,0)"> A(</span>
								<span style="COLOR: rgb(0,0,0)">67</span>
						</font>
						<font size="2">
								<span style="COLOR: rgb(0,0,0)">);<br />        f(A(</span>
								<span style="COLOR: rgb(0,0,0)">77</span>
						</font>
						<span style="COLOR: rgb(0,0,0)">
								<font size="2">));<br />}<br /><br /></font>
						</span>
				</div>
				<br />
		</pre>
		<p>
				<font face="Courier New" size="2">Note that an expression such as: <br /></font>
		</p>
		<pre>
				<font size="2">        A(47)<br /></font>
		</pre>
		<p>
				<font face="Courier New" size="2">is closely related to function-style casts supported by C++. For example: <br /></font>
		</p>
		<pre>
				<font size="2">        double d = 12.34;<br /><br />        int i = int(d);<br /></font>
		</pre>
<img src ="http://www.cppblog.com/mumutou/aggbug/17681.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mumutou/" target="_blank">木木头</a> 2007-01-16 13:21 <a href="http://www.cppblog.com/mumutou/archive/2007/01/16/17681.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++随笔 之 文件操作(转载)</title><link>http://www.cppblog.com/mumutou/archive/2007/01/16/17680.html</link><dc:creator>木木头</dc:creator><author>木木头</author><pubDate>Tue, 16 Jan 2007 05:18:00 GMT</pubDate><guid>http://www.cppblog.com/mumutou/archive/2007/01/16/17680.html</guid><wfw:comment>http://www.cppblog.com/mumutou/comments/17680.html</wfw:comment><comments>http://www.cppblog.com/mumutou/archive/2007/01/16/17680.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mumutou/comments/commentRss/17680.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mumutou/services/trackbacks/17680.html</trackback:ping><description><![CDATA[
		<h2>
				<a id="viewpost1_TitleUrl" href="/lmlf001/archive/2006/04/18/5815.html">
						<font face="Courier New" size="2">C++文件操作</font>
				</a>
				<font face="Courier New" size="2">
				</font>
		</h2>
		<font face="Courier New" size="2"> 原文地址：http://www.layz.net/blog/user1/xuanxuan/archives/2006/67.html<br /> 在C++中，有一个stream这个类，所有的I/O都以这个“流”类为基础的，包括我们要认识的文件I/O，stream这个类有两个重要的运算符： <br /><br />1、插入器(&lt;&lt;) <br />　　向流输出数据。比如说系统有一个默认的标准输出流(cout)，一般情况下就是指的显示器，所以，cout&lt;&lt;"Write Stdout"&lt;&lt;'\n';就表示把字符串"Write Stdout"和换行字符('\n')输出到标准输出流。 <br /><br />2、析取器(&gt;&gt;) <br />　　从流中输入数据。比如说系统有一个默认的标准输入流(cin)，一般情况下就是指的键盘，所以，cin&gt;&gt;x;就表示从标准输入流中读取一个指定类型(即变量x的类型)的数据。 <br /><br />　　在C++中，对文件的操作是通过stream的子类fstream(file stream)来实现的，所以，要用这种方式操作文件，就必须加入头文件fstream.h。下面就把此类的文件操作过程一一道来。 <br /><br />一、打开文件 <br />　　在fstream类中，有一个成员函数open()，就是用来打开文件的，其原型是： <br /><br />void open(const char* filename,int mode,int access); <br /><br />参数： <br /><br />filename：　　要打开的文件名 <br />mode：　　　　要打开文件的方式 <br />access：　　　打开文件的属性 <br />打开文件的方式在类ios(是所有流式I/O类的基类)中定义，常用的值如下： <br /><br />ios::app：　　　以追加的方式打开文件 <br />ios::ate：　　　文件打开后定位到文件尾，ios:app就包含有此属性 <br />ios::binary： 　以二进制方式打开文件，缺省的方式是文本方式。两种方式的区别见前文 <br />ios::in：　　　 文件以输入方式打开 <br />ios::out：　　　文件以输出方式打开 <br />ios::nocreate： 不建立文件，所以文件不存在时打开失败　 <br />ios::noreplace：不覆盖文件，所以打开文件时如果文件存在失败 <br />ios::trunc：　　如果文件存在，把文件长度设为0 <br />　　可以用“或”把以上属性连接起来，如ios::out|ios::binary <br /><br />　　打开文件的属性取值是： <br /><br />0：普通文件，打开访问 <br />1：只读文件 <br />2：隐含文件 <br />4：系统文件 <br />　　可以用“或”或者“+”把以上属性连接起来 ，如3或1|2就是以只读和隐含属性打开文件。 <br /><br />　　例如：以二进制输入方式打开文件c:\config.sys <br /><br />　　fstream file1; <br />　　file1.open("c:\\config.sys",ios::binary|ios::in,0); <br /><br />　　如果open函数只有文件名一个参数，则是以读/写普通文件打开，即： <br /><br />　　file1.open("c:\\config.sys");&lt;=&gt;file1.open("c:\\config.sys",ios::in|ios::out,0); <br /><br />　　另外，fstream还有和open()一样的构造函数，对于上例，在定义的时侯就可以打开文件了： <br /><br />　　fstream file1("c:\\config.sys"); <br /><br />　　特别提出的是，fstream有两个子类：ifstream(input file stream)和ofstream(outpu file stream)，ifstream默认以输入方式打开文件，而ofstream默认以输出方式打开文件。 <br /><br />　　ifstream file2("c:\\pdos.def");//以输入方式打开文件 <br />　　ofstream file3("c:\\x.123");//以输出方式打开文件 <br /><br />　　所以，在实际应用中，根据需要的不同，选择不同的类来定义：如果想以输入方式打开，就用ifstream来定义；如果想以输出方式打开，就用ofstream来定义；如果想以输入/输出方式来打开，就用fstream来定义。 <br /><br />二、关闭文件 <br />　　打开的文件使用完成后一定要关闭，fstream提供了成员函数close()来完成此操作，如：file1.close();就把file1相连的文件关闭。 <br /><br />三、读写文件 <br />　　读写文件分为文本文件和二进制文件的读取，对于文本文件的读取比较简单，用插入器和析取器就可以了；而对于二进制的读取就要复杂些，下要就详细的介绍这两种方式 <br /><br />　　1、文本文件的读写 <br />　　文本文件的读写很简单：用插入器(&lt;&lt;)向文件输出；用析取器(&gt;&gt;)从文件输入。假设file1是以输入方式打开，file2以输出打开。示例如下： <br /><br />　　file2&lt;&lt;"I Love You";//向文件写入字符串"I Love You" <br />　　int i; <br />　　file1&gt;&gt;i;//从文件输入一个整数值。 <br /><br />　　这种方式还有一种简单的格式化能力，比如可以指定输出为16进制等等，具体的格式有以下一些 <br /><br />操纵符 功能 输入/输出 <br />dec 格式化为十进制数值数据 输入和输出 <br />endl 输出一个换行符并刷新此流 输出 <br />ends 输出一个空字符 输出 <br />hex 格式化为十六进制数值数据 输入和输出 <br />oct 格式化为八进制数值数据 输入和输出 <br />setpxecision(int p) 设置浮点数的精度位数 输出 <br /><br />　　比如要把123当作十六进制输出：file1&lt;&lt;&lt;123;要把3.1415926以5位精度输出：FILE1&lt;<setpxecision(5)>&lt;&lt;3.1415926。 <br /><br />　　2、二进制文件的读写 <br />①put() <br />　　put()函数向流写入一个字符，其原型是ofstream &amp;put(char ch)，使用也比较简单，如file1.put('c');就是向流写一个字符'c'。 <br /><br />②get() <br />　　get()函数比较灵活，有3种常用的重载形式： <br /><br />　　一种就是和put()对应的形式：ifstream &amp;get(char &amp;ch);功能是从流中读取一个字符，结果保存在引用ch中，如果到文件尾，返回空字符。如file2.get(x);表示从文件中读取一个字符，并把读取的字符保存在x中。 <br /><br />　　另一种重载形式的原型是： int get();这种形式是从流中返回一个字符，如果到达文件尾，返回EOF，如x=file2.get();和上例功能是一样的。 <br /><br />　　还有一种形式的原型是：ifstream &amp;get(char *buf,int num,char delim='\n')；这种形式把字符读入由 buf 指向的数组，直到读入了 num 个字符或遇到了由 delim 指定的字符，如果没使用 delim 这个参数，将使用缺省值换行符'\n'。例如： <br /><br />　　file2.get(str1,127,'A');//从文件中读取字符到字符串str1，当遇到字符'A'或读取了127个字符时终止。 <br /><br />③读写数据块 <br />　　要读写二进制数据块，使用成员函数read()和write()成员函数，它们原型如下： <br /><br />　　　　read(unsigned char *buf,int num); <br />　　　　write(const unsigned char *buf,int num); <br /><br />　　read()从文件中读取 num 个字符到 buf 指向的缓存中，如果在还未读入 num 个字符时就到了文件尾，可以用成员函数 int gcount();来取得实际读取的字符数；而 write() 从buf 指向的缓存写 num 个字符到文件中，值得注意的是缓存的类型是 unsigned char *，有时可能需要类型转换。 <br /><br />例： <br /><br />　　　　unsigned char str1[]="I Love You"; <br />　　　　int n[5]; <br />　　　　ifstream in("xxx.xxx"); <br />　　　　ofstream out("yyy.yyy"); <br />　　　　out.write(str1,strlen(str1));//把字符串str1全部写到yyy.yyy中 <br />　　　　in.read((unsigned char*)n,sizeof(n));//从xxx.xxx中读取指定个整数，注意类型转换 <br />　　　　in.close();out.close(); <br /><br />四、检测EOF <br />　　成员函数eof()用来检测是否到达文件尾，如果到达文件尾返回非0值，否则返回0。原型是int eof(); <br /><br />例：　　if(in.eof())ShowMessage("已经到达文件尾！"); <br /><br />五、文件定位 <br />　　和C的文件操作方式不同的是，C++ I/O系统管理两个与一个文件相联系的指针。一个是读指针，它说明输入操作在文件中的位置；另一个是写指针，它下次写操作的位置。每次执行输入或输出时，相应的指针自动变化。所以，C++的文件定位分为读位置和写位置的定位，对应的成员函数是 seekg()和 seekp()，seekg()是设置读位置，seekp是设置写位置。它们最通用的形式如下： <br /><br />　　　　istream &amp;seekg(streamoff offset,seek_dir origin); <br />　　　　ostream &amp;seekp(streamoff offset,seek_dir origin); <br /><br />　　streamoff定义于 iostream.h 中，定义有偏移量 offset 所能取得的最大值，seek_dir 表示移动的基准位置，是一个有以下值的枚举： <br /><br />ios::beg：　　文件开头 <br />ios::cur：　　文件当前位置 <br />ios::end：　　文件结尾 <br />　　这两个函数一般用于二进制文件，因为文本文件会因为系统对字符的解释而可能与预想的值不同。 <br /><br />例： <br /><br />　　　　 file1.seekg(1234,ios::cur);//把文件的读指针从当前位置向后移1234个字节 <br />　　　　 file2.seekp(1234,ios::beg);//把文件的写指针从文件开头向后移1234个字节</setpxecision(5)></font>
<img src ="http://www.cppblog.com/mumutou/aggbug/17680.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mumutou/" target="_blank">木木头</a> 2007-01-16 13:18 <a href="http://www.cppblog.com/mumutou/archive/2007/01/16/17680.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++随笔 之 函数模板(Function Template)1 (原创)</title><link>http://www.cppblog.com/mumutou/archive/2007/01/10/17497.html</link><dc:creator>木木头</dc:creator><author>木木头</author><pubDate>Wed, 10 Jan 2007 06:36:00 GMT</pubDate><guid>http://www.cppblog.com/mumutou/archive/2007/01/10/17497.html</guid><wfw:comment>http://www.cppblog.com/mumutou/comments/17497.html</wfw:comment><comments>http://www.cppblog.com/mumutou/archive/2007/01/10/17497.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mumutou/comments/commentRss/17497.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mumutou/services/trackbacks/17497.html</trackback:ping><description><![CDATA[
		<font face="Courier New" size="2">1.Function Template可以针对不同的Template arguments完成一个系列的函数<br />例如<br />template&lt;typename T&gt;<br />inline T const &amp; max(T const &amp;a,T const &amp;b)<br />{<br />   return   a&gt;b?a:b;<br />}<br />2.Function template可以从传递过来的arguments的类型来具体化<br />int a = ::max(10,20);<br />那么Function template 就具体化为<br />inline int const&amp; max(int const &amp;a,int const &amp; b)<br />3.你可以具体指出它的参数类型<br />int a = ::max&lt;int&gt;(10,20);<br />4.Function template可以被重载overloaded<br />inline T const&amp; max(T const &amp;a,T const &amp;b,T const &amp;c)<br />{<br />   return ::max(::max(a,b),c);<br />}<br />当然记住一点，重载的相似点越小越好</font>
<img src ="http://www.cppblog.com/mumutou/aggbug/17497.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mumutou/" target="_blank">木木头</a> 2007-01-10 14:36 <a href="http://www.cppblog.com/mumutou/archive/2007/01/10/17497.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++随笔 之 关于C++中的指针问题 </title><link>http://www.cppblog.com/mumutou/archive/2007/01/09/17458.html</link><dc:creator>木木头</dc:creator><author>木木头</author><pubDate>Tue, 09 Jan 2007 05:48:00 GMT</pubDate><guid>http://www.cppblog.com/mumutou/archive/2007/01/09/17458.html</guid><wfw:comment>http://www.cppblog.com/mumutou/comments/17458.html</wfw:comment><comments>http://www.cppblog.com/mumutou/archive/2007/01/09/17458.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/mumutou/comments/commentRss/17458.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mumutou/services/trackbacks/17458.html</trackback:ping><description><![CDATA[
		<p>
				<font face="Courier New" size="2">原文出处<br /></font>
				<a href="http://community.csdn.net/Expert/topic/5279/5279199.xml?temp=.2457392">
						<font face="Courier New" size="2">http://community.csdn.net/Expert/topic/5279/5279199.xml?temp=.2457392</font>
				</a>
				<br />
				<font face="Courier New" size="2">在文章中大家在讨论一个问题:<br />如果没有存储上没有区别的话,请看下例：<br />float a=3.45;<br />int * p1=&amp;a;<br />float * p2=&amp;a;<br />cout&lt;&lt;"p1"&lt;&lt;"=&gt;"&lt;&lt;*p1&lt;&lt;endl;<br />cout&lt;&lt;"p2"&lt;&lt;"=&gt;"&lt;&lt;*p2&lt;&lt;endl;</font>
		</p>
		<p>
				<font face="Courier New" size="2">结果是：<br />p1=&gt;1107951616<br />p2=&gt;3.45</font>
		</p>
		<p>
				<font face="Courier New" size="2">书上的解释是：p1尽管与p2的地址相同，但它是整型指针，它总是访问该地址中的整型数。<br />首先在32位CPU上面,指针都是4位的,例如0xXX XX XX XX<br />那么既然指针是一样的,那么为什么指针类型不同的话,读出来的数据就变了样呢?<br />这是编译器的问题,例如我有个例子<br /><br />char *p = 'c';<br />int *p1 = 10;<br />在32位机器上面<br />这里面p1是指向4字节的int变量,而p是指向1字节的char 变量<br />这样编译器在用p1变量的时候,会取0x XX XX XX XX后面的4个字节<br />而p变量,只会取0x XX XX XX XX后面的1个字节<br /><br />因为本人现在在网吧里面[不知道大家有没有在网吧里面碰到装有c++编译器的计算机]<br />晚上我给大家一个例子,可以从其内存上面看的很清楚</font>
		</p>
<img src ="http://www.cppblog.com/mumutou/aggbug/17458.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mumutou/" target="_blank">木木头</a> 2007-01-09 13:48 <a href="http://www.cppblog.com/mumutou/archive/2007/01/09/17458.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++随笔 之 泛型编程与设计新思维(转载)</title><link>http://www.cppblog.com/mumutou/archive/2007/01/04/17238.html</link><dc:creator>木木头</dc:creator><author>木木头</author><pubDate>Thu, 04 Jan 2007 07:07:00 GMT</pubDate><guid>http://www.cppblog.com/mumutou/archive/2007/01/04/17238.html</guid><wfw:comment>http://www.cppblog.com/mumutou/comments/17238.html</wfw:comment><comments>http://www.cppblog.com/mumutou/archive/2007/01/04/17238.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mumutou/comments/commentRss/17238.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mumutou/services/trackbacks/17238.html</trackback:ping><description><![CDATA[
		<font face="Courier New" size="2">  <font size="3">作者：徐景周<br /></font><br />   永远记住，编写代码的宗旨在于简单明了，不要使用语言中的冷僻特性，耍小聪明，重要的是编写你理解的代码，理解你编写的代码，这样你可能会做的更好。 </font>
		<div align="right">
				<font face="Courier New" size="2">--- Herb Sutter </font>
		</div>
		<br />
		<font face="Courier New" size="2">    1998年，国际C++标准正式通过，标准化对C++最重要的贡献是：对"强大的抽象概念"给于更有力的支持，以降低软件的复杂度，C++提供了二种功能强大的抽象方法：面向对象编程与泛型编程。面向对象编程大家一定很熟悉了，这里就不再哆嗦了。提到泛型编程(Generic Programming)，有的人可能还不太熟悉，但是提到STL，你就一定会有所耳闻了。STL(Standard Template Library，标准模板库) 其实就是泛型编程的实现品，STL是由Alexander Stepanov(STL之父)、David R Musser和Meng Lee三位大师共同发展，于1994年被纳入C++标准程序库。STL虽然加入C++标准库的时间相对较晚，但它却是C++标准程序库中最具革命性的部分，同时也是C++标准程序库中最重要的组成部分。由于新的C++标准库中几乎每一样东西都是由模板(Template)构成的，当然，STL也不会例外。所以，在这里有必要先概要说明一下模板的有关概念。 <br /><br /><img style="WIDTH: 85px" src="http://www.window07.com/up_files/image/2006-3-5/45488081.gif" /> 模板概念 <br />    通过使用模板可以使程序具有更好的代码重用性。记住，模板是对源代码进行重用，而不是通过继承和组合重用对象代码，当用户使用模板时，参数由编译器来替换。模板由类模板和函数模板二部分组成，以所处理的数据类型的说明作为参数的类就叫类模板，而以所处理的数据类型的说明作为参数的函数叫做函数模板。模板参数可以由类型参数或非类型参数组成，类型参数可用class和typename关键字来指明，二者的意义相同，都表示后面的参数名代表一个潜在的内置或用户定义的类型，非类型参数由一个普通参数声明构成。下面是类模板和函数模板的简单用法： template&lt;class T1, int Size&gt; class Queue // 类模板，其中T1为类型参数，Size为非类型参数 { public: explicit Queue():size_(Size){}; // 显式构造，避免隐式转换 …… template&lt;class T2&gt; void assign(T2 first,T2 last); // 内嵌函数模板 private: T* temp_; int size_; } // 类模板中内嵌函数模板Compare的外围实现(如在Queue类外实现) template&lt;class T1,int Size&gt; template&lt;class T2&gt; void Queue&lt;T1,Size&gt;::assign (T2 first,T2 last) {}; // 模板的使用方法 int ia[4] = {0,1,2,3}; Queue&lt;int, sizeof(ia)/sizeof(int)&gt; qi; qi.assign(ai,ai+4); <img style="WIDTH: 85px" src="http://www.window07.com/up_files/image/2006-3-5/45488081.gif" /> 泛型编程 <br />    泛型编程和面向对象编程不同，它并不要求你通过额外的间接层来调用函数，它让你编写完全一般化并可重复使用的算法，其效率与针对某特定数据类型而设计的算法相同。泛型编程的代表作品STL是一种高效、泛型、可交互操作的软件组件。所谓泛型(Genericity)，是指具有在多种数据类型上皆可操作的含意，与模板有些相似。STL巨大，而且可以扩充，它包含很多计算机基本算法和数据结构，而且将算法与数据结构完全分离，其中算法是泛型的，不与任何特定数据结构或对象类型系在一起。STL以迭代器(Iterators)和容器(Containers)为基础，是一种泛型算法(Generic Algorithms)库，容器的存在使这些算法有东西可以操作。STL包含各种泛型算法(algorithms)、泛型指针(iterators)、泛型容器(containers)以及函数对象(function objects)。STL并非只是一些有用组件的集合，它是描述软件组件抽象需求条件的一个正规而有条理的架构。 <br />    迭代器(Iterators)是STL的核心，它们是泛型指针，是一种指向其他对象(objects)的对象，迭代器能够遍历由对象所形成的区间(range)。迭代器让我们得以将容器(containers)与作用其上的算法(algorithms)分离，大多数的算法自身并不直接操作于容器上，而是操作于迭代器所形成的区间中。迭代器一般分为五种：Input Iterator、Output Iterator、Forward Iterator、Bidirections Iterator和Random Access Iterator。Input Iterator就象只从输入区间中读取数据一样，具有只读性，属于单向移动，如STL中的istream_iterator。Output Iterator刚好相反，只写出数据到输出区间中，具有只写性，属于单向移动，如STL中的ostream_iterator。Forward Iterator也属于单向移动，但不同之处是它同时具有数据读、写性。Bidirections Iterator如名称暗示，支持双向移动，不但可以累加(++)取得下一个元素，而且可以递减(--)取前一个元素，支持读、写性。Random Access Iterator功能最强，除了以上各迭代器的功能外，还支持随机元素访问(p+=n)，下标(p[n])、相减(p1-p2)及前后次序关系(p1&lt;p2)等。Input Iterator和Output Iterator属于同等最弱的二种迭代器，Forward Iterator是前二者功能的强化(refinement)，Bidirections Iterator又是Forward Iterator迭代器的强化，最后Random Access Iterator又是Bidirections Iterator迭代器的强化。如下简单示例展示Input Iterator、Forward Iterator、Bidirections Iterator和Radom Access Iterator迭代器的功能（其中input_iterator_tag等带tag字符串为各不同迭代器的专属标识）： <br />1、InputIterator template&lt;class InputIterator, class Distance&gt; void advance(InputIterator&amp; i, Distance n, input_iterator_tag) { for(; n&gt;0; --n,++i){} // InputIterator具有++性 } 2、ForwardIterator template&lt;class ForwardIterator, class Distance&gt; void advance(ForwardIterator&amp; i, Distance n,forward_iterator_tag) { advance(i, n, input_iterator_tag()); } 3、BidirectionalIterator template&lt;class BidirectionalIterator, class Distance&gt; void advance(BidirectionalIterator&amp; i, Distance n, bidirectional_iterator_tag) { if(n&gt;=0) // 具有++、--性 for(; n&gt;0; --n,++i){} else for(; n&gt;0; ++n,--i){} } 4、RandomAccessIterator template&lt;class RandomAccessIterator, class Distance&gt; void advance(RandomAccessIterator&amp; i, Distance n, random_access_iterator_tag) { i += n; // 具有++、--、+=等性 }     函数对象(Function object)也称仿函数(Functor)，是一种能以一般函数调用语法来调用的对象，函数指针(Function pointer)是一种函数对象，所有具有operator()操作符重载的成员函数也是函数对象。函数对象一般分为无参函数(Generator)，单参函数(Unary Function)和双参函数(Binary Function)三种形式，它们分别能以f()、f(x)和f(x,y)的形式被调用，STL定义的其他所有函数对象都是这三种概念的强化。如下简单示例展示几种形式的实现：<br /><br />1、无参(Generator)形式 struct counter { typedef int result_type; counter(result_type init=0):n(init){} result_type operator() { return n++;} result_type n; } 2、单参(Unary Function)形式 template&lt;class Number&gt; struct even // 函数对象even，找出第一个偶数 { bool operator()(Number x) const {return (x&amp;1) == 0;} } // 使用算法find_if在区间A到A+N中找到满足函数对象even的元素 int A[] = {1,0,3,4}; const int N=sizeof(A)/sizeof(int); find_if(A,A+N, even&lt;int&gt;()); 3、双参(Binary Function)形式 struct ltstr { bool operator()(const char* s1, const char* s2) const { return strcmp(s1&lt;s2) &lt; 0;} }; // 使用函数对象ltstr，输出set容器中A和B的并集 const int N=3 const char* a[N] = {"xjz","xzh","gh"}; const char* b[N]= {"jzx","zhx","abc"}; set&lt;const char*,ltstr&gt; A(a,a+N); set&lt;const char*,ltstr&gt; B(b,b+N); set_union(A.begin(),A.end(),B.begin(),B.end(), ostream_iterator&lt;const char*&gt;(cout," "), ltstr());     容器(container)是一种对象(object)，可以包含并管理其它的对象，并提供迭代器(iterators)用以定址其所包含之元素。根据迭代器种类的不同，容器也分为几中，以Input Iterator为迭代器的一般container，以Forward Iterator为迭代器的Forward Container，以Bidirectional Iterator 为迭代器的Reversible Container，以Random Access Iterator为迭代器的Random Access Container。STL定义二种大小可变的容器：序列式容器(Sequence Container)和关联式容器(Associative Container)序列式容器包括vector、list和deque，关联式容器包括set、map、multiset和multimap。以下示例简单说明部分容器的使用： 1、vector使用 // 将A中以元素5为分割点，分别排序，使排序后5后面的元素都大于5之前的元素(后区间不排序)， // 然后输出 int main() { int A[] = {7,2,6,4,5,8,9,3,1}; const int N=sizeof(A)/sizeof(int); vector&lt;int&gt; V(A,A+N); partial_sort(V,V+5,V+N); copy(V,V+N,ostream_iterator&lt;int&gt;(cout," ")); cout &lt;&lt; endl; } 输出可能是：1 2 3 4 5 8 9 7 6 2、list使用 // 产生一空list，插入元素后排序，然后输出 int main() { list&lt;int&gt; L1; L1.push_back(0); L1.push_front(1); L1.insert(++L1.begin,3); L1.sort(); copy(L1.begin(),L1.end(),ostream_iterator&lt;int&gt;(cout," ")); } 输出：0 1 3 3、deque使用 int main() { deque&lt;int&gt; Q; Q.push_back(3); Q.push_front(1); Q.insert(Q.begin()+1,2); Copy(Q.begin(),Q.end(),ostream_iterator&lt;int&gt;(cout," ")); } 输出：1 2 3 4、map使用 int main() { map&lt;string,int&gt; M; M.insert(make_pair("A",11); pair&lt;map&lt;string,int&gt;::iterator, bool&gt; p = M.insert(make_pair("C",5)); if(p.second) cout &lt;&lt; p.first-&gt;second&lt;&lt;endl; } 输出：5 5、multiset使用 int main() { const int N = 5; int a[N] = {4,1,1,3,5}; multiset&lt;int&gt; A(a,a+N); copy(A.begin(),A.end(),ostream_iterator&lt;int&gt;(cout," ")); } 输出：1 1 3 4 5 <img style="WIDTH: 85px" src="http://www.window07.com/up_files/image/2006-3-5/45488081.gif" /> 设计新思维 <br />    将设计模式(design patterns)、泛型编程(generic programming)和面向对象编程(object-oriented programming)有机的结合起来，便形成了设计新思维。其中，设计模式是经过提炼的出色设计方法，对于很多情况下碰到的问题，它都是合理而可复用的解决方案；泛型编程是一种典范(paradigm)，专注于将类型抽象化，形成功能需求方面的一个精细集合，并利用这些需求来实现算法，相同的算法可以运用于广泛的类型集中，所谓泛型，就是具有在多种数据类型上皆可操作的含意；最后同面象对象编程中的多态(polymorphism)和模板(templates)等技术相结合，便获得极高层次上的具有可复用性的泛型组件。泛型组件预先实现了设计模块，可以让用户指定类型和行为，从而形成合理的设计，主要特点是灵活、通用和易用。 <br />    policies和policy类，是一种重要的类设计技术，所谓policy，是用来定义一个类或类模板的接口，该接口由下列之一或全部组成：内部类型定义、成员函数和成员变量。基于policy的类由许多小型类(称为policies)组成，每一个这样的小型类只负责单纯如行为或结构的某一方面。Policies机制由模板和多重继承组成，它们可以互相混合搭配，从而形成设计戎的多样性，通过plicy类，不但可以定制行为，也可以定制结构。 <br /><br />下面简单举例说明泛化思维和面向对象思维在部分设计模式中的运用。 <br /><br />    Singletons设计模式泛化实现 Singleton模式是一种保证一个对象(class)只有一个实体，并为它提供一个全局访问点。Singleton是一种经过改进的全局变量，既在程序中只能有唯一实体的类型，它的重点主要集中在产生和管理一个独立对象上，而且不允许产生另一个这样的对象。 <br />先让我们看看一般的C++实现的基本手法，下面是实现源码： // Singleton.h文件中 class Singleton { public: static Singleton&amp; Instance() { if(!pInstance_){ if(destroyed_){ // 引用是否已经失效 OnDeadReference(); } else { Create(); // 第一次时创建实例 } } return *pInstance_; } private: Singleton(); // 禁止默认构造 Singleton(const Singleton&amp;); // 禁止拷贝构造 Singleton&amp; operator= (const Singleton&amp;);　 // 禁止赋值操作 static void Create() // 传加创建的实例引用 { static Singleton theInstance; pInstance_ = &amp;theInstance; } static void OnDeadReference() { throw std::runtime_error(" 实例被不正当消毁"); } virtual ~Singleton() { pInstance- = 0; destroyed_ = true; } static Singleton *pInstance_; static bool destroyed_; } // Singleton.cpp中静态成员变量初始化 Singleton* Singleton::pInstance_ = 0; Bool Singleton::destroyed_ = false;     如上所示，Singleton模式实现中只有一个public成员Instance()用来第一次使用时创建单一实例，当第二次使用时静态变量将已经被设定好，不会再次创建实例。还将默认构造函数、拷贝构造函数和赋值操作符放在private中，目地是不让用户使用它们。另外，为避免实例意外消毁后再实例化情况，加入静态布尔变量destroy_来进行判断是否出错，从而达到稳定性。<br />    从上面一般实现可以看出Singleton模式实现主要在于创建(Creation)方面和生存期(Lifetime)方面，既可以通过各种方法来创建Singleton。Creation必然能创建和摧毁对象，必然要开放这两个相应函数，将创建作为独立策略分离开来是必需的，这样你就可以创建多态对象了，所以泛化Singleton并不拥有Creator对象，它被放在CreationPolicy&lt;T&gt;类模板之中。生命期是指要遵循C++规则，后创建都先摧毁，负责程序生命期某一时刻摧毁Singleton对象。 <br /><br />下面是一个简单的泛化Singleton模式的实现(不考虑线程因素) template &lt; class T, template&lt;class&gt; calss CreationPolicy = CreateUsingNew, template&lt;class&gt; class LifetimePolicy=DefaultLifetime, &gt; classs SingletonHolder { public: static T&amp; Instance() { if(!pInstance_) { if(destroyed_) { LifetimePolicy&lt;T&gt;::OnDeadReference(); destroyed_ = false; } pInstance_ = CreationPolicy&lt;T&gt;::Create(); LifetimePolicy&lt;T&gt;::SchedultCall(&amp;DestorySingleton); } return *pInstance_; } private: static void DestroySinleton() { assert(!destroyed_); CreationPlicy&lt;T&gt;::Destroy(pInstance_); pInstance_ = 0; destroyed_ = true; } SingletonHolder(); SingletonHolder (const SingletonHolder &amp;); SingletonHolder &amp; operator= (const SingletonHolder &amp;);　 Static T* pInstance_; Static bool destroyed_; };     Instance()是SingletonHolder开放的唯一一个public函数，它在CreationPolicy、LifetimePolicy中打造了一层外壳。其中模板参数类型T，接收类名，既需要进行Singleton的类。模板参数内的类模板缺省参数CreateUsingNew是指通过new操作符和默认构造函数来产生对象，DefaultLifetime是通过C++规则来管理生命期。LifetimePolicy&lt;T&gt;中有二个成员函数，ScheduleDestrution()函数接受一个函数指针，指向析构操作的实际执行函数，如上面DestorySingleton析构函数；OnDeadReference()函数同上面一般C++中同名函数相同，是负责发现失效实例来抛出异常的。CreationPlicy&lt;T&gt;中的Create()和Destroy()两函数是用来创建并摧毁具体对象的。 <br /><br />下面是上述泛化Singleton模式实现的使用： <br /><br />1、应用一 class A{}; typedef SingletonHolder&lt;A, CreateUsingNew&gt; SingleA; 2、应用二 class A{}; class Derived : public A {}; template&lt;class T&gt; struct MyCreator : public CreateUsingNew&lt;T&gt; { static T* Create() { return new Derived; } static void Destroy(T* pInstance) { delete pInstance; } } typedef SingletonHolder&lt;A,MyCreator&gt; SingleA;     通过上面示例可以看出， SingletonHolder采用基于plicy设计实现，它将Singleton对象分解为数个policies，模板参数类中CreationPolicy和LifetimePolicy相当于二个policies封装体。利用它们可以协助制作出使用者自定义的Singleton对象，同时还预留了调整和扩展的空间。由此而得，泛型组件(generic components)，是一种可复用的设计模板，结合了模板和模式，是C++中创造可扩充设计的新方法，提供了从设计到代码的简易过渡，帮助我们编写清晰、灵活、高度可复用的代码。 <br /><br /><img style="WIDTH: 85px" src="http://www.window07.com/up_files/image/2006-3-5/45488081.gif" /> 参考文献 </font>
		<ul>
				<li>
						<font face="Courier New" size="2">C++ Primer(第三版) --- 潘爱民等译 </font>
				</li>
				<li>
						<font face="Courier New" size="2">Effective C++(第二版) --- 侯捷译 </font>
				</li>
				<li>
						<font face="Courier New" size="2">More Effective C++ --- 侯捷译 </font>
				</li>
				<li>
						<font face="Courier New" size="2">Exceptional C++ --- 卓小涛译 </font>
				</li>
				<li>
						<font face="Courier New" size="2">More Exceptional C++ --- 於春景译 </font>
				</li>
				<li>
						<font face="Courier New" size="2">深度探索C++对象模型 --- 侯捷译 </font>
				</li>
				<li>
						<font face="Courier New" size="2">泛型编程与STL --- 侯捷译 </font>
				</li>
				<li>
						<font face="Courier New" size="2">C++ STL程序员开发指南 --- 彭木根等箸 </font>
				</li>
				<li>
						<font face="Courier New" size="2">设计模式：可复用面向对象软件的元素 --- 李英军等译 </font>
				</li>
				<li>
						<font face="Courier New" size="2">C++设计新思维 --- 侯捷等译 </font>
				</li>
		</ul>
<img src ="http://www.cppblog.com/mumutou/aggbug/17238.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mumutou/" target="_blank">木木头</a> 2007-01-04 15:07 <a href="http://www.cppblog.com/mumutou/archive/2007/01/04/17238.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++随笔 之 STL[vector]的存储技术(原创)</title><link>http://www.cppblog.com/mumutou/archive/2007/01/04/17231.html</link><dc:creator>木木头</dc:creator><author>木木头</author><pubDate>Thu, 04 Jan 2007 06:26:00 GMT</pubDate><guid>http://www.cppblog.com/mumutou/archive/2007/01/04/17231.html</guid><wfw:comment>http://www.cppblog.com/mumutou/comments/17231.html</wfw:comment><comments>http://www.cppblog.com/mumutou/archive/2007/01/04/17231.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/mumutou/comments/commentRss/17231.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mumutou/services/trackbacks/17231.html</trackback:ping><description><![CDATA[
		<font face="Courier New" size="2">首先我们先来看Example Code:<br />#include &lt;vector&gt;<br />#include &lt;iostream&gt;<br />#include &lt;memory&gt;<br />using namespace std;<br />void main()<br />{<br /> vector&lt;int&gt; v;<br />// cout&lt;&lt;v.allocator;<br /> v.push_back(0);<br /> v.push_back(1);<br /> v.push_back(2);<br /> v.push_back(3);<br /> v.push_back(4);<br /> v.push_back(5);<br /> cout&lt;&lt;v.max_size();<br />}<br />利用VC6.0的内存调试<br /> v.push_back(0);之后<br />//_First迭代器00481B40<br />//_Last迭代器00481B44<br />//_End迭代器004B1B44<br /> v.push_back(1);之后<br />//_First迭代器00481B00<br />//_Last迭代器00481B08<br />//_End迭代器004B1B08<br /><font style="BACKGROUND-COLOR: #800080" color="#ffffff">为什么在执行一次push_back之后,迭代器全部会变呢?</font><br />下面我们看看P.J. Plauger的代码<br /> void insert(iterator _P, size_type _M, const _Ty&amp; _X)<br />  {if (_End - _Last &lt; _M)<br />   {size_type _N = size() + (_M &lt; size() ? size() : _M);<br />   iterator _S = allocator.allocate(_N, (void *)0);<br />   iterator _Q = _Ucopy(_First, _P, _S);<br />   _Ufill(_Q, _M, _X);<br />   _Ucopy(_P, _Last, _Q + _M);<br />   _Destroy(_First, _Last);<br />   allocator.deallocate(_First, _End - _First);<br />   _End = _S + _N;<br />   _Last = _S + size() + _M;<br />   _First = _S; }<br />  else if (_Last - _P &lt; _M)<br />   {_Ucopy(_P, _Last, _P + _M);<br />   _Ufill(_Last, _M - (_Last - _P), _X);<br />   fill(_P, _Last, _X);<br />   _Last += _M; }<br />  else if (0 &lt; _M)<br />   {_Ucopy(_Last - _M, _Last, _Last);<br />   copy_backward(_P, _Last - _M, _Last);<br />   fill(_P, _P + _M, _X);<br />   _Last += _M; }}<br /><br />其中M = 1;<br />当_End - _Last &lt; _M时,就要重新分配内存了,哦原来时这样的.<br /><font color="#ff1493">[个人认为,在方便调试的时候,可以把C:\MSDEV\VC98\Include\下面的vector文件中的protected改成public:]</font><br />下面我给出在5次插入之后其内存分配<br />push_back(2)<br />//00481AC0<br />//00481ACC<br />//00481AD0<br />push_back(3);<br />//00481AC0<br />//00481AD0<br />//00481AD0<br />push_back(4);<br />//00481B20<br />//00481B34<br />//00481B40<br />push_back(5);<br />//00481B20<br />//00481B38<br />//00481B40<br />注意没有,_Last - _First之后的明显是size() * 4<br />[注:在VC6.0的STL版本是采用的PJSTL版本,是一种公认最垃圾的STL版本<br />在C++ Builder中的STL版本是采用的RW版本,Rouge Wave公司<br />在unix下面GCC采用的是SGI Silicon Graphics Computer System Inc公司STL版本,我认为在可读性,可移植性方面最好的一个版本]<br /></font>
<img src ="http://www.cppblog.com/mumutou/aggbug/17231.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mumutou/" target="_blank">木木头</a> 2007-01-04 14:26 <a href="http://www.cppblog.com/mumutou/archive/2007/01/04/17231.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>