﻿<?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/firehutter/category/2700.html</link><description>雕栏玉砌应犹在，只是朱颜改</description><language>zh-cn</language><lastBuildDate>Mon, 19 May 2008 21:55:40 GMT</lastBuildDate><pubDate>Mon, 19 May 2008 21:55:40 GMT</pubDate><ttl>60</ttl><item><title>C++学习笔记：类继承中关于虚函数和动态联编的几点问题</title><link>http://www.cppblog.com/firehutter/archive/2006/11/29/15785.html</link><dc:creator>爱上青菜的包子</dc:creator><author>爱上青菜的包子</author><pubDate>Wed, 29 Nov 2006 09:27:00 GMT</pubDate><guid>http://www.cppblog.com/firehutter/archive/2006/11/29/15785.html</guid><wfw:comment>http://www.cppblog.com/firehutter/comments/15785.html</wfw:comment><comments>http://www.cppblog.com/firehutter/archive/2006/11/29/15785.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/firehutter/comments/commentRss/15785.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/firehutter/services/trackbacks/15785.html</trackback:ping><description><![CDATA[首先需要确认的是，编译器对非虚方法使用静态联编，对虚方法使用动态联编。<br />看起来，在大多数情况下，动态联编都更好，因为它让程序能够选择为特定类型设计的方法，这样问题就来了，既然动态联编这么好，为什么还要设计两种类型的联编？为什么默认的联编方法是静态的而不是动态？<br /><br />原因关键就在于效率。Strousstrup说过（很经典，呵呵）：C++的指导原则之一是，不要为不使用的特性付出代价（内存或处理时间）。<br /><br />因为通常情况下，编译器处理虚函数的方法为：给每个对象添加一个隐藏成员，该成员中保存了一个指向函数地址数组的指针（称为虚函数表 virtual function table,vtbl）。虚函数表中存储了为类对象进行声明的虚函数的地址。例如，基类包含一个指针，指向了基类中所有虚函数的地址表，派生类对象将包含一个指向独立地址表的指针，如果派生类提供了虚函数的新定义，该虚函数表将保存新函数的地址，如果没有重新定义，则保留原始版本的地址。调用虚函数时，程序将查看存储在对象中的vtbl地址，然后转向相应的函数地址表。<br /><br />所以显而易见的是，使用虚函数时，在内存和执行速度方面有一定的额外成本，包括：<br />每个对象都将增大，增大量为存储地址的空间；对每个类，编译器都创建一个虚函数地址表（数组）；每个函数调用都需要执行一步额外的操作，即到表中查找地址。<br /><br />所以咱们要养成的习惯是，在设计类时，可能包含一些不在派生类重新定义的成员函数，那么这些函数就不要设置为虚函数。这样首先会有更好的效率，其次被声明为虚函数的成员函数就表明是预期在派生类中会被重新定义的，在阅读代码时也将比较方便。<img src ="http://www.cppblog.com/firehutter/aggbug/15785.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/firehutter/" target="_blank">爱上青菜的包子</a> 2006-11-29 17:27 <a href="http://www.cppblog.com/firehutter/archive/2006/11/29/15785.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>这两天用C++Builder时碰到一点问题，关于TQuary的</title><link>http://www.cppblog.com/firehutter/archive/2006/10/26/14255.html</link><dc:creator>爱上青菜的包子</dc:creator><author>爱上青菜的包子</author><pubDate>Thu, 26 Oct 2006 13:25:00 GMT</pubDate><guid>http://www.cppblog.com/firehutter/archive/2006/10/26/14255.html</guid><wfw:comment>http://www.cppblog.com/firehutter/comments/14255.html</wfw:comment><comments>http://www.cppblog.com/firehutter/archive/2006/10/26/14255.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/firehutter/comments/commentRss/14255.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/firehutter/services/trackbacks/14255.html</trackback:ping><description><![CDATA[
		<p>这几天拿到公司以前项目中的一个用C++Builder做的程序，在我机器上调试，结果提示出错：Operation not applicable</p>
		<p>使用断点跟踪之后发现错误出在使用TQuery时执行open方法时，回追根源，得出以下反馈：<br /></p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">m_pqQuery</span>
				<span style="COLOR: #000000">-&gt;</span>
				<span style="COLOR: #000000">SQL</span>
				<span style="COLOR: #000000">-&gt;</span>
				<span style="COLOR: #000000">Add( </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">Select * From Table1 Where Id = :PId </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000"> );<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />m_pqQuery</span>
				<span style="COLOR: #000000">-&gt;</span>
				<span style="COLOR: #000000">ParamByName( </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">PId</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000"> )</span>
				<span style="COLOR: #000000">-&gt;</span>
				<span style="COLOR: #000000">AsInteger     </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> 某个int变量;</span>
		</div>
		<p>
				<br />执行完这句之后，按正常情况，参数PId应该被赋予了一个整形值，但是Debug跟踪显示其值还是跟未赋值前是同样表示的未知值。所以在执行open方法时出错了。</p>
		<p>如果我不是用该方法，直接把SQL语句写死：<br /></p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">m_pqQuery</span>
				<span style="COLOR: #000000">-&gt;</span>
				<span style="COLOR: #000000">SQL</span>
				<span style="COLOR: #000000">-&gt;</span>
				<span style="COLOR: #000000">Add( </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">Select * From Table1 Where Id = 0 </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000"> );</span>
		</div>
		<p>
				<br />运行正常</p>
		<p>或者用<br /></p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000"> sql[</span>
				<span style="COLOR: #000000">80</span>
				<span style="COLOR: #000000">];<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> n </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> 某整形变量 ;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />sprintf(sql,</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">Select * From Table1 Where Id = %d</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">,n);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />pqQuery</span>
				<span style="COLOR: #000000">-&gt;</span>
				<span style="COLOR: #000000">SQL</span>
				<span style="COLOR: #000000">-&gt;</span>
				<span style="COLOR: #000000">Add(sql);</span>
		</div>
		<p>
				<br />也运行正常</p>
		<p>查了下，原来给参数赋值的方法并没有错误，编译也能通过，况且以前该程序肯定是能正常运行的。。真是奇怪为什么在我这里就赋不上值。。调试了很久也没能找到原因，只好作罢，为了顺利运行，只能改为sprintf和直接连接字符串的方式。<br />在这里记上一笔，希望以后能够找到原因。。。<br /></p>
<img src ="http://www.cppblog.com/firehutter/aggbug/14255.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/firehutter/" target="_blank">爱上青菜的包子</a> 2006-10-26 21:25 <a href="http://www.cppblog.com/firehutter/archive/2006/10/26/14255.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++学习笔记：类与动态内存分配中各种问题的阶段性总结</title><link>http://www.cppblog.com/firehutter/archive/2006/09/28/13111.html</link><dc:creator>爱上青菜的包子</dc:creator><author>爱上青菜的包子</author><pubDate>Thu, 28 Sep 2006 07:18:00 GMT</pubDate><guid>http://www.cppblog.com/firehutter/archive/2006/09/28/13111.html</guid><wfw:comment>http://www.cppblog.com/firehutter/comments/13111.html</wfw:comment><comments>http://www.cppblog.com/firehutter/archive/2006/09/28/13111.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/firehutter/comments/commentRss/13111.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/firehutter/services/trackbacks/13111.html</trackback:ping><description><![CDATA[
		<ol>
				<li>重载&lt;&lt;操作符<br />要重新定义&lt;&lt;操作符，以便将它和cout一起用来显示对象的内容，请定义下面的友元操作符函数： 
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">ostream </span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">operator</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> (ostream </span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> os,</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> c_name </span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> obj)<br /><img id="Codehighlighter1_56_106_Open_Image" onclick="this.style.display='none'; Codehighlighter1_56_106_Open_Text.style.display='none'; Codehighlighter1_56_106_Closed_Image.style.display='inline'; Codehighlighter1_56_106_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_56_106_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_56_106_Closed_Text.style.display='none'; Codehighlighter1_56_106_Open_Image.style.display='inline'; Codehighlighter1_56_106_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_56_106_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_56_106_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />os </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> <img src="http://www.cppblog.com/images/dot.gif" />;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> display object contents</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> os;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div><br />其中c_name是类名。如果该类提供了能够返回所需内容的公有方法，则可在操作符函数中使用这些方法，这样便不会将他们设置为友元函数了。<br /></li>
				<li>转换函数<br />要将单个值转换为类类型，需要创建原型如下所示的类构造函数： 
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">c_name(type_name value);</span></div><br />其中c_name为类名，type_name是要转换的类型的名称。<br />要将类转换为其他类型，需要创建原型如下所示的类成员函数：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">operator</span><span style="COLOR: #000000"> type_name();</span></div><br />虽然该函数没有声明返回类型，但应返回所需类型的值。<br />使用转换函数时要小心。可以在声明构造函数时使用关键字explicit，以防止它被用于隐式转换。<br /></li>
				<li>其构造函数使用new的类<br />如果类使用new操作符来分配类成员指向的内存，在设计时应采取一些预防措施。 </li>
		</ol>
		<ul>
				<li>对于指向的内存是由new分配的所有类成员，都应在类的析构函数中对其使用delete，该操作符将释放分配的内存。 
</li>
				<li>如果析构函数通过对指针类成员使用delete来释放内存，则每个构造函数都应当使用new来初始化指针，或将它设置为空指针。 
</li>
				<li>构造函数中要么使用new[]，要么使用new，而不能混用。如果构造函数使用的是new[]，则析构函数应使用delete[]；如果构造函数使用的是new，则析构函数应适用delete。 
</li>
				<li>应定义一个分配内存（而不是将指针指向已有内存）的复制构造函数。这样程序能够将类对象初始化为另一个对象。这种构造函数原型如下： 
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">className(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> className </span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">)</span></div></li>
				<li>应定义一个重载赋值操作符的类成员函数，其函数定义如下（其中c_pointer是c_name的类成员，类型为指向type_name的指针）。下面的范例假设使用new[]来初始化变量c_pointer）： 
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">c_name </span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> c_name::</span><span style="COLOR: #0000ff">operator</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> c_name </span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> cn)<br /><img id="Codehighlighter1_48_291_Open_Image" onclick="this.style.display='none'; Codehighlighter1_48_291_Open_Text.style.display='none'; Codehighlighter1_48_291_Closed_Image.style.display='inline'; Codehighlighter1_48_291_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_48_291_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_48_291_Closed_Text.style.display='none'; Codehighlighter1_48_291_Open_Image.style.display='inline'; Codehighlighter1_48_291_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_48_291_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_48_291_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> cn)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />delete [] c_pointer;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> set size number of type_name units to be copyied</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">c_pointer </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> type_name[size];<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> then copy data pointed to by cn.c_pointer to<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> location pointed to by c_pointer</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000"><img src="http://www.cppblog.com/images/dot.gif" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div></li>
		</ul>
		<p>本文对我前面几篇随笔中提到的问题也作出了一个总结，感觉很有必要记下来。<br />以上内容原文引用自参考书籍中内容。<br /><br />参考书籍：C++PrimerPlus author:Stephen Prata<br /><br /></p>
<img src ="http://www.cppblog.com/firehutter/aggbug/13111.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/firehutter/" target="_blank">爱上青菜的包子</a> 2006-09-28 15:18 <a href="http://www.cppblog.com/firehutter/archive/2006/09/28/13111.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++学习笔记：关于C++类与动态内存分配中布局new操作符</title><link>http://www.cppblog.com/firehutter/archive/2006/09/28/13107.html</link><dc:creator>爱上青菜的包子</dc:creator><author>爱上青菜的包子</author><pubDate>Thu, 28 Sep 2006 06:42:00 GMT</pubDate><guid>http://www.cppblog.com/firehutter/archive/2006/09/28/13107.html</guid><wfw:comment>http://www.cppblog.com/firehutter/comments/13107.html</wfw:comment><comments>http://www.cppblog.com/firehutter/archive/2006/09/28/13107.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/firehutter/comments/commentRss/13107.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/firehutter/services/trackbacks/13107.html</trackback:ping><description><![CDATA[
		<p> </p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> BUF </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">512</span>
				<span style="COLOR: #000000"> ;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> JustTesting<br /><img id="Codehighlighter1_41_157_Open_Image" onclick="this.style.display='none'; Codehighlighter1_41_157_Open_Text.style.display='none'; Codehighlighter1_41_157_Closed_Image.style.display='inline'; Codehighlighter1_41_157_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_41_157_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_41_157_Closed_Text.style.display='none'; Codehighlighter1_41_157_Open_Image.style.display='inline'; Codehighlighter1_41_157_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_41_157_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_41_157_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">private</span>
						<span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        JustTesting(</span>
						<span style="COLOR: #0000ff">const</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">string</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">&amp;</span>
						<span style="COLOR: #000000"> s </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">Just Testing</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">,</span>
						<span style="COLOR: #0000ff">int</span>
						<span style="COLOR: #000000"> n </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">0</span>
						<span style="COLOR: #000000">)<br /><img id="Codehighlighter1_114_118_Open_Image" onclick="this.style.display='none'; Codehighlighter1_114_118_Open_Text.style.display='none'; Codehighlighter1_114_118_Closed_Image.style.display='inline'; Codehighlighter1_114_118_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_114_118_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_114_118_Closed_Text.style.display='none'; Codehighlighter1_114_118_Open_Image.style.display='inline'; Codehighlighter1_114_118_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />        </span>
						<span id="Codehighlighter1_114_118_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_114_118_Open_Text">
								<span style="COLOR: #000000">{<img src="http://www.cppblog.com/images/dot.gif" />}</span>
						</span>
						<span style="COLOR: #000000"> <br /><img id="Codehighlighter1_137_141_Open_Image" onclick="this.style.display='none'; Codehighlighter1_137_141_Open_Text.style.display='none'; Codehighlighter1_137_141_Closed_Image.style.display='inline'; Codehighlighter1_137_141_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_137_141_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_137_141_Closed_Text.style.display='none'; Codehighlighter1_137_141_Open_Image.style.display='inline'; Codehighlighter1_137_141_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />        </span>
						<span style="COLOR: #000000">~</span>
						<span style="COLOR: #000000">JustTesting()</span>
						<span id="Codehighlighter1_137_141_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_137_141_Open_Text">
								<span style="COLOR: #000000">{<img src="http://www.cppblog.com/images/dot.gif" />}</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    <img src="http://www.cppblog.com/images/dot.gif" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> main()<br /><img id="Codehighlighter1_172_565_Open_Image" onclick="this.style.display='none'; Codehighlighter1_172_565_Open_Text.style.display='none'; Codehighlighter1_172_565_Closed_Image.style.display='inline'; Codehighlighter1_172_565_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_172_565_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_172_565_Closed_Text.style.display='none'; Codehighlighter1_172_565_Open_Image.style.display='inline'; Codehighlighter1_172_565_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_172_565_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_172_565_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">char</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">*</span>
						<span style="COLOR: #000000"> buffer </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">new</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">char</span>
						<span style="COLOR: #000000"> [BUF];<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    JustTesting </span>
						<span style="COLOR: #000000">*</span>
						<span style="COLOR: #000000">pc1,</span>
						<span style="COLOR: #000000">*</span>
						<span style="COLOR: #000000">pc2,</span>
						<span style="COLOR: #000000">*</span>
						<span style="COLOR: #000000">pc3,</span>
						<span style="COLOR: #000000">*</span>
						<span style="COLOR: #000000">pc4;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pc1 </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">new</span>
						<span style="COLOR: #000000"> (buffer) JustTesting;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pc2 </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">new</span>
						<span style="COLOR: #000000"> JustTesting( </span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000"> Heap1 </span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000"> , </span>
						<span style="COLOR: #000000">20</span>
						<span style="COLOR: #000000"> );<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pc3 </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">new</span>
						<span style="COLOR: #000000"> (buffer </span>
						<span style="COLOR: #000000">+</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">sizeof</span>
						<span style="COLOR: #000000"> (JustTesting)) JustTesting(</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">Bad Idea</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">,</span>
						<span style="COLOR: #000000">6</span>
						<span style="COLOR: #000000">);  </span>
						<span style="COLOR: #008000">//</span>
						<span style="COLOR: #008000"> 此处用一个JustTesging对象大小的偏移量避免pc3与pc1占用同一块内存，因为如果类动态的为其成员分配内存，占用同一内存将会产生问题。 </span>
						<span style="COLOR: #008000">
								<br />
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
						</span>
						<span style="COLOR: #000000">    pc4 </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">new</span>
						<span style="COLOR: #000000"> JustTesting(</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">Heap2</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">,</span>
						<span style="COLOR: #000000">10</span>
						<span style="COLOR: #000000">) <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    <img src="http://www.cppblog.com/images/dot.gif" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    delete pc2;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    delete pc4;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    delete [] buffer;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">return</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">0</span>
						<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
		</div>
		<p>
				<br />以上代码片断中，pc1和pc3为布局new操作符来分配内存，而pc2和pc4为常规new操作符来分配内存 。<br />对于常规new操作符分配的内存，可以直接使用：<span style="COLOR: #000000"><span class="Code"><span style="COLOR: #000000">delete pc2; </span></span></span>这样的语句操作来释放内存。<br /><br />而对于布局new操作符分配的内存就不能这样做：<span style="COLOR: #000000"><span class="Code"><span style="COLOR: #000000">delete pc1;</span></span></span></p>
		<p>因为pc1和pc3并没有直接收到new操作符返回的地址，而是由布局操作符指向了buffer的地址，new/delete系统知道已分配的512字节块buffer，但对布局new操作符对该内存块做了何种处理一无所知。<br />另一方面，buffer的地址是用<font color="#000000"><span class="Code">new []</span>初始化的，因此必须使用<span class="Code">delete[]</span>而不是<span class="Code">delete</span></font>。<br /><font color="#ff0000">注意：即使buffer是使用new而不是new[]初始化的，<span class="Code">delete pc1 </span>也将释放buffer，而不是pc1。</font></p>
		<p>以上的代码确实释放了buffer：<font color="#000000"><span class="Code">delete [] buffer;</span><br /></font>但是由此产生了新的问题，它没有为布局new操作符在该内存块中创建的对象调用析构函数，我们只需要在析构函数中放入一段显示语句就可以清楚的看到，程序并没有销毁“JustTesting”和“Bad Idea”，也就是pc1和pc3指向的对象。<br />那么这里就需要我们显式的为布局new操作符创建的对象调用析构函数。正常情况下将自动调用析构函数，<font color="#ff0000">这是需要显示调用析构函数的少数几种情况之一。</font><br />显式调用析构函数时，必须指定要销毁的对象。由于有指向对象的指针，因此可以这样写：</p>
		<div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 95%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
				<div>
						<span id="_162_532_Open_Text">
								<span style="COLOR: #000000">pc3-&gt;~JustTesting();<br />pc1-&gt;~JustTesting();</span>
						</span>
				</div>
		</div>
		<p>把这段代码放到<span class="Code">delete [] buffer;</span>之前，这段程序才算完整无错。</p>
		<p>参考书籍：C++PrimerPlus author:Stephen Prata<br /></p>
<img src ="http://www.cppblog.com/firehutter/aggbug/13107.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/firehutter/" target="_blank">爱上青菜的包子</a> 2006-09-28 14:42 <a href="http://www.cppblog.com/firehutter/archive/2006/09/28/13107.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++学习笔记：在构造函数中使用new时应注意的事项</title><link>http://www.cppblog.com/firehutter/archive/2006/09/28/13106.html</link><dc:creator>爱上青菜的包子</dc:creator><author>爱上青菜的包子</author><pubDate>Thu, 28 Sep 2006 06:41:00 GMT</pubDate><guid>http://www.cppblog.com/firehutter/archive/2006/09/28/13106.html</guid><wfw:comment>http://www.cppblog.com/firehutter/comments/13106.html</wfw:comment><comments>http://www.cppblog.com/firehutter/archive/2006/09/28/13106.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/firehutter/comments/commentRss/13106.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/firehutter/services/trackbacks/13106.html</trackback:ping><description><![CDATA[
		<p>在使用new来初始化对象的指针成员时必须特别小心，以下是几点注意事项：</p>
		<ul>
				<li>如果在构造函数中使用new来初始化指针成员，则应在析构函数中使用delete。 
</li>
				<li>new和delete必须相互兼容。new对应于delete，new[]对应于delete[]。 
</li>
				<li>如果有多个构造函数，则必须以相同的方式使用new，要么都带中括号，要么都不带。因为只有一个析构函数，因此所有的构造函数都必须与它兼容。<font color="#ff0000">不过可以在一个构造函数中使用new来初始化指针，而在另外一个构造函数中将指针初始化为空（Null或0），这是因为delete（无论是带中括号还是不带中括号）可以用于空指针。</font></li>
		</ul>
<img src ="http://www.cppblog.com/firehutter/aggbug/13106.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/firehutter/" target="_blank">爱上青菜的包子</a> 2006-09-28 14:41 <a href="http://www.cppblog.com/firehutter/archive/2006/09/28/13106.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++学习笔记：C++类和动态内存分配中关于复制构造函数和赋值操作符</title><link>http://www.cppblog.com/firehutter/archive/2006/09/28/13103.html</link><dc:creator>爱上青菜的包子</dc:creator><author>爱上青菜的包子</author><pubDate>Thu, 28 Sep 2006 06:33:00 GMT</pubDate><guid>http://www.cppblog.com/firehutter/archive/2006/09/28/13103.html</guid><wfw:comment>http://www.cppblog.com/firehutter/comments/13103.html</wfw:comment><comments>http://www.cppblog.com/firehutter/archive/2006/09/28/13103.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/firehutter/comments/commentRss/13103.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/firehutter/services/trackbacks/13103.html</trackback:ping><description><![CDATA[
		<p>例如有以下class：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> StringBad<br /><img id="Codehighlighter1_16_135_Open_Image" onclick="this.style.display='none'; Codehighlighter1_16_135_Open_Text.style.display='none'; Codehighlighter1_16_135_Closed_Image.style.display='inline'; Codehighlighter1_16_135_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_16_135_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_16_135_Closed_Text.style.display='none'; Codehighlighter1_16_135_Open_Image.style.display='inline'; Codehighlighter1_16_135_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_16_135_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_16_135_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">private</span>
						<span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        </span>
						<span style="COLOR: #0000ff">char</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">*</span>
						<span style="COLOR: #000000"> str;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        </span>
						<span style="COLOR: #0000ff">int</span>
						<span style="COLOR: #000000"> len;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />         <img src="http://www.cppblog.com/images/dot.gif" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        StringBad(</span>
						<span style="COLOR: #0000ff">const</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">char</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">*</span>
						<span style="COLOR: #000000"> s);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        StringBad();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        </span>
						<span style="COLOR: #000000">~</span>
						<span style="COLOR: #000000">StringBad();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        <img src="http://www.cppblog.com/images/dot.gif" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">;</span>
		</div>
		<p>
		</p>
		<p>
		</p>
		<p>
		</p>
		<p>在构造函数和析构函数定义当中有如下定义：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">StringBad::StringBad(</span>
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000"> s)<br /><img id="Codehighlighter1_37_94_Open_Image" onclick="this.style.display='none'; Codehighlighter1_37_94_Open_Text.style.display='none'; Codehighlighter1_37_94_Closed_Image.style.display='inline'; Codehighlighter1_37_94_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_37_94_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_37_94_Closed_Text.style.display='none'; Codehighlighter1_37_94_Open_Image.style.display='inline'; Codehighlighter1_37_94_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_37_94_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_37_94_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    len </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> std::strlen(s);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    str </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">new</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">char</span>
						<span style="COLOR: #000000"> [len </span>
						<span style="COLOR: #000000">+</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">1</span>
						<span style="COLOR: #000000">];<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    <img src="http://www.cppblog.com/images/dot.gif" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000"> <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />StringBad::StringBad()<br /><img id="Codehighlighter1_121_159_Open_Image" onclick="this.style.display='none'; Codehighlighter1_121_159_Open_Text.style.display='none'; Codehighlighter1_121_159_Closed_Image.style.display='inline'; Codehighlighter1_121_159_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_121_159_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_121_159_Closed_Text.style.display='none'; Codehighlighter1_121_159_Open_Image.style.display='inline'; Codehighlighter1_121_159_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_121_159_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_121_159_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    len </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">4</span>
						<span style="COLOR: #000000"> ;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    str </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">new</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">char</span>
						<span style="COLOR: #000000">[</span>
						<span style="COLOR: #000000">4</span>
						<span style="COLOR: #000000">];<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    <img src="http://www.cppblog.com/images/dot.gif" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000"> <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />StringBad::</span>
				<span style="COLOR: #000000">~</span>
				<span style="COLOR: #000000">StringBad()<br /><img id="Codehighlighter1_187_210_Open_Image" onclick="this.style.display='none'; Codehighlighter1_187_210_Open_Text.style.display='none'; Codehighlighter1_187_210_Closed_Image.style.display='inline'; Codehighlighter1_187_210_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_187_210_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_187_210_Closed_Text.style.display='none'; Codehighlighter1_187_210_Open_Image.style.display='inline'; Codehighlighter1_187_210_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_187_210_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_187_210_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    <img src="http://www.cppblog.com/images/dot.gif" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    delete [] str;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
		</div>
		<p>
		</p>
		<p>
		</p>
		<p>
		</p>
		<p>
		</p>
		<p>
		</p>
		<p>那么在程序当中如果有以下代码：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" src_cetemp="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" />
				<span style="COLOR: #000000">StringBad sports(</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">Spinach Leaves Bow1 for bollars</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">);<br /><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" src_cetemp="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" />StringBad sailor </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> sports;</span>
		</div>
		<p>以上的第二条初始化语句将会调用什么构造函数？<font color="#ff0000">记住</font>，这种形式的初始化等效于下面的语句：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" src_cetemp="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" />
				<span style="COLOR: #000000">StringBad sailor </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> StringBad(sports);</span>
		</div>
		<p>因为sports的类型为StringBad，因此相应的构造函数原型应该如下：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" src_cetemp="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" />
				<span style="COLOR: #000000">StringBad(</span>
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000"> StringBad </span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">);</span>
		</div>
		<p>当我们使用一个对象来初始化另一个对象时，编译器将自动生成上述构造函数（称为复制构造函数，因为它创建对象的一个副本）。<br />现在我们不妨总结一下所谓的隐式成员函数，即C++自动提供了以下这些成员函数：</p>
		<ul>
				<li>默认构造函数，如果没有定义构造函数。 
</li>
				<li>复制构造函数，如果没有定义。 
</li>
				<li>赋值操作符，如果没有定义。 
</li>
				<li>默认析构函数，如果没有定义。 
</li>
				<li>地址操作符，如果没有定义。 </li>
		</ul>
		<p>现在我们来看看我们没有定义复制构造函数的情况下调用隐式复制构造函数将会出现什么情况。<br />从构造函数定义的代码片断可以看到，当中使用new操作符初始化了一个指针str，而隐式的复制构造函数是按值进行复制的，那么对于指针str，将会进行如下复制：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" src_cetemp="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" />
				<span style="COLOR: #000000">sailor.str </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> sports.str;</span>
		</div>
		<p>
				<font color="#ff0000">这里复制的不是字符串，而是一个指向字符串的指针！</font>也就是说，我们将得到两个指向同一个字符串的指针！由此会产生的问题将不言而喻。当其中一个对象调用了析构函数之后，其str指向的内存将被释放，这个时候我们如果调用另一个对象，其str指向的地址数据会是什么？很明显将会出现不可预料的结果。</p>
		<p>所以由此可见，<strong>如果类中包含了使用new初始化的指针成员，应当定义一个复制构造函数，以复制指向的数据，而不是指针，这被称为深度复制。因为默认的浅复制（或成为成员复制）仅浅浅的赋值指针信息。</strong></p>
		<p>我们再看以下代码片断，我们稍做修改：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" src_cetemp="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" />
				<span style="COLOR: #000000">StringBad headline1(</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">Celery Stalks at Midnight</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">);<br /><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" src_cetemp="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" />StringBad knot;<br /><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" src_cetemp="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" />knot </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> headline1;</span>
		</div>
		<p>这里的最后一行将与以上例子有所区别，现在是将已有对象赋给另一个已有对象，这将会采取其他操作，即使用重载的赋值操作符。（我们需要知道的是：初始化总是会调用复制构造函数，而使用=操作符时也可能调用赋值操作符）因为C++允许对象赋值，这是通过自动为类重载赋值操作符实现的。其原型如下：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" src_cetemp="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" />
				<span style="COLOR: #000000">Class_name </span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000"> Class_name::</span>
				<span style="COLOR: #0000ff">operator</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> (</span>
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000"> Class_name </span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">);</span>
		</div>
		<p>它接受并返回一个指向类对象的引用。<br />与隐式的复制构造函数一样，隐式的对象赋值操作符也会产生同样的问题，即包含了使用new初始化的指针成员时，只会采用浅复制。所以我们需要使用同样的解决办法，<strong>即定义一个重载的赋值操作符来实现深度复制。</strong></p>
		<p>
				<strong>所以综上所述，如果类中包含了使用new初始化的指针成员，我们应该显式定义一个复制构造函数和一个重载的赋值操作符来实现其深度复制，避免由此带来的成员复制问题<br /><br /></strong>参考书籍：C++PrimerPlus author:Stephen Prata</p>
<img src ="http://www.cppblog.com/firehutter/aggbug/13103.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/firehutter/" target="_blank">爱上青菜的包子</a> 2006-09-28 14:33 <a href="http://www.cppblog.com/firehutter/archive/2006/09/28/13103.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于C++学习笔记</title><link>http://www.cppblog.com/firehutter/archive/2006/09/28/13102.html</link><dc:creator>爱上青菜的包子</dc:creator><author>爱上青菜的包子</author><pubDate>Thu, 28 Sep 2006 06:23:00 GMT</pubDate><guid>http://www.cppblog.com/firehutter/archive/2006/09/28/13102.html</guid><wfw:comment>http://www.cppblog.com/firehutter/comments/13102.html</wfw:comment><comments>http://www.cppblog.com/firehutter/archive/2006/09/28/13102.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/firehutter/comments/commentRss/13102.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/firehutter/services/trackbacks/13102.html</trackback:ping><description><![CDATA[很喜欢C++，学习也有一段时间了。但是看书+练手的同时，总感觉有必要将自己学习中觉得重要的地方整理出来，以便以后回头参考。最终选择了cppblog，呵呵。以后就在这里安家了~~<br />笔记中参考了一些书籍中的范例和一些说明。都是自己学习过程中整理出来的，主要目的是给自己日后参考。<img src ="http://www.cppblog.com/firehutter/aggbug/13102.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/firehutter/" target="_blank">爱上青菜的包子</a> 2006-09-28 14:23 <a href="http://www.cppblog.com/firehutter/archive/2006/09/28/13102.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>