﻿<?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++博客-futual -文章分类-C++小知识</title><link>http://www.cppblog.com/strawberry/category/18860.html</link><description>  </description><language>zh-cn</language><lastBuildDate>Tue, 10 Apr 2012 05:23:33 GMT</lastBuildDate><pubDate>Tue, 10 Apr 2012 05:23:33 GMT</pubDate><ttl>60</ttl><item><title>成员函数的运算符重载与友元函数的运算符重载</title><link>http://www.cppblog.com/strawberry/articles/168528.html</link><dc:creator>futual</dc:creator><author>futual</author><pubDate>Wed, 21 Mar 2012 10:53:00 GMT</pubDate><guid>http://www.cppblog.com/strawberry/articles/168528.html</guid><wfw:comment>http://www.cppblog.com/strawberry/comments/168528.html</wfw:comment><comments>http://www.cppblog.com/strawberry/articles/168528.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/strawberry/comments/commentRss/168528.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/strawberry/services/trackbacks/168528.html</trackback:ping><description><![CDATA[<span style="color: rgb(51,51,51); line-height: 25px"><font size="2"><font face="arial"><span style="font-size: small">1.对双目</span></font><span style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" href="tag.php?name=%E8%BF%90%E7%AE%97%E7%AC%A6"><font face="arial"><span style="font-size: small">运算符</span></font></span><font face="arial"><span style="font-size: small">而言，成员</span></font><span style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" href="tag.php?name=%E5%87%BD%E6%95%B0"><font face="arial"><span style="font-size: small">函数</span></font></span><span style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" href="tag.php?name=%E9%87%8D%E8%BD%BD"><font face="arial"><span style="font-size: small">重载</span></font></span></font><font size="2"><font face="arial"><span style="font-size: small">运算符的函数参数表中只有一个参数，而用友元函数重载运算符函数参数表中含有两个参数。<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp;&nbsp;对单木运算符来说，成员函数重载运算符的函数参数表中没有参数，而用友元函数重载运算符函数参数表中含有一个函数。这个问题要搞清楚，有一个this</span></font><span style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" href="tag.php?name=%E6%8C%87%E9%92%88"><font face="arial"><span style="font-size: small">指针</span></font></span></font><font face="arial" size="2"><span style="font-size: small">的问题。。。<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />2.双目运算符一般可以用友元函数重载和成员函数重载，但有一种情况只可以用友元函数重载。<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp;&nbsp;即：双目运算符左边的变量是一个常量，而不是对象！！！这点很重要的额。</span></font></span> 
<div><span style="color: rgb(51,51,51); line-height: 25px"><span style="line-height: 25px">
<hr />
</span><font face="arial" size="2"><span style="font-size: small">书上推荐的一般经验：<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp; &nbsp;1.对于单目运算符，建议选择成员函数；<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp; &nbsp;2.对于运算符&#8220;=，（），[]，-&gt;&#8221;只能作为成员函数；<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp; &nbsp;3.对于运算符&#8220;+ =，-=，/=，*=，&amp;=，！=，~=，%=，&lt;&lt;=，&gt;&gt;=&#8221;建议重载为成员函数；<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp; &nbsp;4.对于其他运算符，建议重载为友元函数。</span></font></span></div>
<div><span style="font-size: 17px; color: rgb(51,51,51); line-height: 25px"><font face="宋体"></font><font size="2">
<hr />
</font><span style="font-size: 12px; color: rgb(0,0,0); line-height: normal; font-family: song, Verdana; border-collapse: collapse">
<div><font size="2"><font face="arial"><span style="font-size: small">对于class中将operator函数定义为friend主要有以下考虑：</span></font><span style="font-size: small; line-height: 20px; font-family: arial">&nbsp;</span></font></div>
<div><font size="2"><font face="arial"><span style="font-size: small">1.friend function是对外公开的，而class method是属于对象的，有些情况调用不方便</span></font><span style="font-size: small; line-height: 20px; font-family: arial">&nbsp;</span><span style="font-size: small; line-height: 20px; font-family: arial">&nbsp;</span></font></div>
<div><font size="2"><font face="arial"><span style="font-size: small">2.对某些需要两个参数的operator function，定义friend比较方便，如下例中operator &lt;&lt;</span></font><span style="font-size: small; line-height: 20px; font-family: arial">&nbsp;</span></font></div>
<div><font face="arial" size="2"><span style="font-size: small">3.所有class &nbsp; method必须有匹配的左值类型进行调用而friend则无需这样，只要能隐式转化成当前类型就可以调用该函数，因此如下例构造函数没有定义为explicit的，可以进行隐式转化，就可以在不同类型间运算。&nbsp;&nbsp;&nbsp;<br style="font: 12px normal song, Verdana" /></span></font></div>
<div><font size="2"><font face="arial"><span style="font-size: small">下面的例子可以很好的说明定义为friend &nbsp; function的好处. &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; #include &nbsp; &lt;iostream.h&gt; &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; class &nbsp; point &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; { &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp; x; &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp; y; &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public: &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; point(int &nbsp; vx=0){x=vx;y=0;} &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; point(int &nbsp; vx,int &nbsp; vy):x(vx),y(vy){} &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; friend &nbsp; point &nbsp; operator &nbsp; +(point &nbsp; p1,point &nbsp; p2); &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; friend &nbsp; ostream &nbsp; &amp; &nbsp; operator &nbsp; &lt;&lt;(ostream &nbsp; &amp;output,point &nbsp; &amp;p1); &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; }; &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; point &nbsp; operator &nbsp; +(point &nbsp; p1,point &nbsp; p2) &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; { &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; point &nbsp; p; &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p.x=p1.x+p2.x; &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p.y=p1.y+p2.y; &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; p; &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; } &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp;&nbsp;</span></font><font color="#0000ff"><font face="arial"><span style="font-size: small">ostream &nbsp; &amp; &nbsp; operator &nbsp; &lt;&lt;(ostream &nbsp; &amp;output,point &nbsp; &amp;p1)</span></font></font></font><font size="2"><font face="arial"><span style="font-size: small">&nbsp;&nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; { &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; output&lt;&lt;p1.x&lt;&lt;'+'&lt;&lt;p1.y&lt;&lt;'i'&lt;&lt;endl; &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; output; &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; } &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; int &nbsp; main() &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; { &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp; &nbsp; &nbsp; point &nbsp; p1(1,2),p2(5,6); &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp; &nbsp; &nbsp; point &nbsp; p3,p4; &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp; &nbsp; &nbsp; p3=p1+p2; &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp; &nbsp; &nbsp; p4=1+p2</span></font><font color="#ff0000"><font face="arial"><span style="font-size: small">;//如果定义为class &nbsp; method,编译将出错!类提供了相应的构造函数，且非explicit</span></font></font></font><font face="arial" size="2"><span style="font-size: small">&nbsp;&nbsp; &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp; &nbsp; &nbsp; cout&lt;&lt;p1&lt;&lt;p2; &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp; &nbsp; &nbsp; cout&lt;&lt;p3&lt;&lt;p4; &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; &nbsp; 0; &nbsp;&nbsp;<br style="font: 12px normal song, Verdana" />&nbsp; }&nbsp;&nbsp;&nbsp;</span></font></div></span></span></div><img src ="http://www.cppblog.com/strawberry/aggbug/168528.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/strawberry/" target="_blank">futual</a> 2012-03-21 18:53 <a href="http://www.cppblog.com/strawberry/articles/168528.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C/C++数组名与指针区别   （转载  来源：天极网  http://tech.163.com/05/0823/11/1RR94CAS00091589.html）</title><link>http://www.cppblog.com/strawberry/articles/168312.html</link><dc:creator>futual</dc:creator><author>futual</author><pubDate>Mon, 19 Mar 2012 05:20:00 GMT</pubDate><guid>http://www.cppblog.com/strawberry/articles/168312.html</guid><wfw:comment>http://www.cppblog.com/strawberry/comments/168312.html</wfw:comment><comments>http://www.cppblog.com/strawberry/articles/168312.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/strawberry/comments/commentRss/168312.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/strawberry/services/trackbacks/168312.html</trackback:ping><description><![CDATA[　<strong>引言</strong><br /><br />　　指针是C/C++语言的特色，而数组名与指针有太多的相似，甚至很多时候，数组名可以作为指针使用。于是乎，很多程序<a href="http://tech.163.com/special/A/00091593/Arts1.html" target="_blank">设计</a>者就被搞糊涂了。而许多的大学老师，他们在C语言的教学过程中也错误得给学生讲解："数组名就是指针"。很幸运，我的大学老师就是其中之一。时至今日，我日复一日地进行着C/C++项目的<a href="http://tech.163.com/special/d/0009159F/developer.html" target="_blank">开发</a>，而身边还一直充满这样的程序员，他们保留着"数组名就是指针"的误解。<br /><br />　　想必这种误解的根源在于国内某著名的C程序设计<a href="http://tech.163.com/school">教程</a>。如果这篇文章能够纠正许多中国程序员对数组名和指针的误解，笔者就不甚欣慰了。借此文，笔者站在无数对知识如饥似渴的中国程序员之中，深深寄希望于国内的计算机图书编写者们，能以"深入<a href="http://tech.163.com/special/y/00091536/yzts2.html" target="_blank">探索</a>"的思维方式和精益求精的认真态度来对待图书编写工作，但愿市面上多一些融入作者思考结晶的心血之作！<br /><br />　　<strong>魔幻数组名</strong><br /><br />　　请看程序（本文程序在WIN32平台下编译）：<br /><br /><code>1. #include &lt;iostream.h&gt;<br />2. int main(int argc, char* argv[])<br />3. {<br />4. 　char str[10];<br />5. 　char *pStr = str;<br />6. 　cout &lt;&lt; sizeof(str) &lt;&lt; endl;<br />7. 　cout &lt;&lt; sizeof(pStr) &lt;&lt; endl;<br />8. 　return 0;<br />9. }</code><br />　　1、数组名不是指针<br /><br />　　我们先来推翻"数组名就是指针"的说法，用反证法。<br /><br />　　证明　数组名不是指针<br /><br />　　假设：数组名是指针；<br /><br />　　则：pStr和str都是指针；<br /><br />　　因为：在WIN32平台下，指针长度为4；<br /><br />　　所以：第6行和第7行的输出都应该为4；<br /><br />　　实际情况是：第6行输出10，第7行输出4；<br /><br />　　所以：假设不成立，数组名不是指针<br /><br />　　2、数组名神似指针<br /><br />　　上面我们已经证明了数组名的确不是指针，但是我们再看看程序的第5行。该行程序将数组名直接赋值给指针，这显得数组名又的确是个指针！<br /><br />　　我们还可以<a href="http://tech.163.com/special/k/00091536/kgfx2.html" target="_blank">发现</a>数组名显得像指针的例子：<br /><br /><code>1. #include &lt;string.h&gt;<br />2. #include &lt;iostream.h&gt;<br />3. int main(int argc, char* argv[])<br />4. {<br />5. 　char str1[10] = "I Love U";<br />6. 　char str2[10]; <br />7. 　strcpy(str2,str1);<br />8. 　cout &lt;&lt; "string array 1: " &lt;&lt; str1 &lt;&lt; endl;<br />9. 　cout &lt;&lt; "string array 2: " &lt;&lt; str2 &lt;&lt; endl;<br />10.　 return 0;<br />11. }</code><br />　　标准C库函数strcpy的函数原形中能接纳的两个参数都为char型指针，而我们在调用中传给它的却是两个数组名！函数输出：<br /><br /><code>string array 1: I Love U<br />string array 2: I Love U</code><br />　　数组名再一次显得像指针！<br /><br />　　既然数组名不是指针，而为什么到处都把数组名当指针用？于是乎，许多程序员得出这样的结论：数组名（主）是（谓）不是指针的指针（宾）。<br /><br />　　整个一魔鬼。<br /><br />　　<strong>揭密数组名</strong><br /><br />　　现在到揭露数组名本质的时候了，先给出三个结论：<br /><br />　　(1)数组名的内涵在于其指代实体是一种数据结构，这种数据结构就是数组；<br /><br />　　(2)数组名的外延在于其可以转换为指向其指代实体的指针，而且是一个指针常量；<br /><br />　　(3)指向数组的指针则是另外一种变量类型（在WIN32平台下，长度为4），仅仅意味着数组的存放地址！<br /><br />　　1、数组名指代一种数据结构：数组<br /><br />　　现在可以解释为什么第1个程序第6行的输出为10的问题，根据结论1，数组名str的内涵为一种数据结构，即一个长度为10的char型数组，所以sizeof(str)的结果为这个数据结构占据的内存大小：10字节。<br /><br />　　再看：<br /><br /><code>1. int intArray[10];<br />2. cout &lt;&lt; sizeof(intArray) ;</code><br />　　第2行的输出结果为40（整型数组占据的内存空间大小）。<br /><br />　　如果C/C++程序可以这样写：<br /><br /><code>1. int[10] intArray;<br />2. cout &lt;&lt; sizeof(intArray) ;</code><br />　　我们就都明白了，intArray定义为int[10]这种数据结构的一个实例，可惜啊，C/C++目前并不支持这种定义方式。<br /><br />　　2、数组名可作为指针常量<br /><br />　　根据结论2，数组名可以转换为指向其指代实体的指针，所以程序1中的第5行数组名直接赋值给指针，程序2第7行直接将数组名作为指针形参都可成立。<br /><br />　　下面的程序成立吗？<br /><br /><code>1. int intArray[10];<br />2. intArray++;</code><br />　　读者可以编译之，发现编译出错。原因在于，虽然数组名可以转换为指向其指代实体的指针，但是它只能被看作一个指针常量，不能被修改。 <br /><br />　　而指针，不管是指向结构体、数组还是基本数据类型的指针，都不包含原始数据结构的内涵，在WIN32平台下，sizeof操作的结果都是4。<br />顺便纠正一下许多程序员的另一个误解。许多程序员以为sizeof是一个函数，而实际上，它是一个操作符，不过其使用方式看起来的确太像一个函数了。语句sizeof(int)就可以说明sizeof的确不是一个函数，因为函数接纳形参（一个变量），世界上没有一个C/C++函数接纳一个数据类型（如int）为"形参"。<br /><br />　　3、数据名可能失去其数据结构内涵 <br /><br />　　到这里似乎数组名魔幻问题已经宣告圆满解决，但是平静的湖面上却再次掀起波浪。请看下面一段程序：<br /><br /><code>1. #include &lt;iostream.h&gt;<br />2. void arrayTest(char str[])<br />3. {<br />4. 　cout &lt;&lt; sizeof(str) &lt;&lt; endl;<br />5. }<br />6. int main(int argc, char* argv[])<br />7. {<br />8. 　char str1[10] = "I Love U";<br />9. 　arrayTest(str1); <br />10.　 return 0;<br />11. }</code><br />　　程序的输出结果为4。不可能吧？<br /><br />　　一个可怕的数字，前面已经提到其为指针的长度!<br /><br />　　结论1指出，数据名内涵为数组这种数据结构，在arrayTest函数体内，str是数组名，那为什么sizeof的结果却是指针的长度？这是因为：<br /><br />　　(1)数组名作为函数形参时，在函数体内，其失去了本身的内涵，仅仅只是一个指针；<br /><br />　　(2)很遗憾，在失去其内涵的同时，它还失去了其常量特性，可以作自增、自减等操作，可以被修改。<br /><br />　　所以，数据名作为函数形参时，其全面沦落为一个普通指针！它的贵族身份被剥夺，成了一个地地道道的只拥有4个字节的平民。<br /><br />　　以上就是结论4。<br /><br />　　<strong>结束语</strong><br /><br />　　最后，笔者再次表达深深的希望，愿我和我的同道中人能够真正以谨慎的研究态度来认真思考开发中的问题，这样才能在我们中间产生大师级的程序员，顶级的开发书籍。每次拿着美国鬼子的开发书籍，我们不免发出这样的感慨：我们落后太远了。 <img src ="http://www.cppblog.com/strawberry/aggbug/168312.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/strawberry/" target="_blank">futual</a> 2012-03-19 13:20 <a href="http://www.cppblog.com/strawberry/articles/168312.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CString/string/char */int 比较详解 及  转换</title><link>http://www.cppblog.com/strawberry/articles/168241.html</link><dc:creator>futual</dc:creator><author>futual</author><pubDate>Sun, 18 Mar 2012 03:38:00 GMT</pubDate><guid>http://www.cppblog.com/strawberry/articles/168241.html</guid><wfw:comment>http://www.cppblog.com/strawberry/comments/168241.html</wfw:comment><comments>http://www.cppblog.com/strawberry/articles/168241.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/strawberry/comments/commentRss/168241.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/strawberry/services/trackbacks/168241.html</trackback:ping><description><![CDATA[&nbsp;关键点：&lt;CStirng&gt;主要用于MFC的编写，而&lt;string&gt;属于STL，两者都是符合标准<a class="channel_keylink" href="http://c.chinaitlab.com/" target="_blank">C++</a>的，但是在非 windows平台或者说VC上还是用&lt;string&gt;吧。另外还有一个&lt;string.h&gt;这是传统<a class="channel_keylink" href="http://c.chinaitlab.com/" target="_blank">C++</a>才有的~ 
<p>&nbsp;&nbsp;&nbsp; （一） 概述</p>
<p>&nbsp;&nbsp;&nbsp; string和CString均是字符串模板类，string为标准模板类（STL）定义的字符串类，已经纳入C++标准之中；</p>
<p>&nbsp;&nbsp;&nbsp; CString（typedef CStringT&gt; CString）为Visual C++中最常用的字符串类，继承自CSimpleStringT类，主要应用在MFC和ATL编程中，主要数据类型有char（应用于 ANSI），wchar_t（unicode），TCHAR（ANSI与unicode均可）；</p>
<p>&nbsp;&nbsp;&nbsp; char*为C编程中最常用的字符串指针，一般以'\0'为结束标志；</p>
<p>&nbsp;&nbsp;&nbsp; （二） 构造</p>
<p>&nbsp;&nbsp;&nbsp; string是方便的，可以从几乎所有的字符串构造而来，包括CString和char*；</p>
<p>&nbsp;&nbsp;&nbsp; CString次之，可以从基本的一些字符串变量构造而来，包括char*等；</p>
<p>&nbsp;&nbsp;&nbsp; char*没有构造函数，仅可以赋值；</p>
<p>&nbsp;&nbsp;&nbsp; 举例：</p>
<p>&nbsp;&nbsp;&nbsp; char* psz = &#8220;joise&#8221;；</p>
<p>&nbsp;&nbsp;&nbsp; CString cstr（ psz ）；</p>
<p>&nbsp;&nbsp;&nbsp; string str（ cstr ）；</p>
<p>&nbsp;&nbsp;&nbsp; （三） 运算符重载</p>
<p>&nbsp;&nbsp;&nbsp; a） operator=</p>
<p>&nbsp;&nbsp;&nbsp; string是最方便的，几乎可以直接用所有的字符串赋值，包括CString和char*；</p>
<p>&nbsp;&nbsp;&nbsp; CString次之，可以直接用些基本的字符串赋值，包括char*等；</p>
<p>&nbsp;&nbsp;&nbsp; char*只能由指针赋值，并且是极危险的操作，建议使用strcpy或者memcpy，而且char*在声明的时候如未赋初值建议先设为NULL，以避免野指针；</p>
<p>&nbsp;&nbsp;&nbsp; 举例：<br />
<table bordercolor="#cccccc" cellspacing="0" cellpadding="3" width="100%" bgcolor="#ffffff" border="2">
<tbody>
<tr>
<td>&nbsp;char *psz = NULL;<br />psz = new char[10]; //当然，以上的直接写成char *psz = new char[10];也是一样<br />memset( psz, 0, 10 );<br />strcpy( psz, &#8220;joise&#8221; );<br />CString cstr;<br />cstr = psz;<br />string str;<br />str = psz;<br />str = cstr;<br />delete []psz</td></tr></tbody></table></p>
<p>&nbsp;&nbsp;&nbsp; b） operator+</p>
<p>&nbsp;&nbsp;&nbsp; string与CString差不多，可以直接与char*进行加法，但不可以相互使用+运算符，即string str = str + cstr是非法的，须转换成char*；</p>
<p>&nbsp;&nbsp;&nbsp; char*没有+运算，只能使用strcat把两个指针连在一起；</p>
<p>&nbsp;&nbsp;&nbsp; 举例：<br />
<table bordercolor="#cccccc" cellspacing="0" cellpadding="3" width="100%" bgcolor="#ffffff" border="2">
<tbody>
<tr>
<td>&nbsp;char* psz = &#8220;joise&#8221;;<br />CString cstr = psz;<br />cstr = cstr + psz;<br />string str = psz;<br />str = str + str + psz;<br />strcat( psz, psz );<br />strcat( psz, cstr );//合法<br />strcat( psz, str );//非法，由此可见，CString可自动转换为const char*，而string不行<br /></td></tr></tbody></table></p>
<p>&nbsp;&nbsp;&nbsp; c） operator +=</p>
<p>&nbsp;&nbsp;&nbsp; string是最强大的，几乎可以与所有的字符串变量+=，包括CString和char*；</p>
<p>&nbsp;&nbsp;&nbsp; CString次之，可以与基本的一些字符串变量进行+=而来，包括char*等；</p>
<p>&nbsp;&nbsp;&nbsp; char*没有+=运算符，只能使用strcat把两个指针连在一起；</p>
<p>&nbsp;&nbsp;&nbsp; d） operator[]</p>
<p>&nbsp;&nbsp;&nbsp; CString最好，当越界时会抛出断言异常；</p>
<p>&nbsp;&nbsp;&nbsp; string与char*下标越界结果未定义；</p>
<p>&nbsp;&nbsp;&nbsp; 举例：<br />
<table bordercolor="#cccccc" cellspacing="0" cellpadding="3" width="100%" bgcolor="#ffffff" border="2">
<tbody>
<tr>
<td>&nbsp;char* psz = &#8220;joise&#8221;;<br />CString cstr = psz;<br />cout &lt;&lt; cstr[8];<br />string str = psz;<br />cout &lt;&lt; str[8];<br />cout &lt;&lt; psz[8];</td></tr></tbody></table></p>&nbsp;&nbsp;&nbsp; e） operator== 、operator！=、operator&gt; 、operator&lt; 、operator&gt;= 、perator&lt;= CString与string之间不可以进行比较，但均可以与char*进行比较，并且比较的是值，而不是地址；<br />
<table bordercolor="#cccccc" cellspacing="0" cellpadding="3" width="100%" bgcolor="#ffffff" border="2">
<tbody>
<tr>
<td>&nbsp;cout &lt;&lt; ( psz == cstr );<br />cout &lt;&lt; ( psz == str );<br />cout &lt;&lt; ( str == psz );<br />cout &lt;&lt; ( cstr == psz );//以上代码返回均为1</td></tr></tbody></table>
<p>&nbsp;&nbsp;&nbsp; （四） 常用算法</p>
<p>&nbsp;&nbsp;&nbsp; a） 查找</p>
<p>&nbsp;&nbsp;&nbsp; 作用 char* string CString</p>
<p>&nbsp;&nbsp;&nbsp; 查找指定值 strchr</p>
<p>&nbsp;&nbsp;&nbsp; strstr</p>
<p>&nbsp;&nbsp;&nbsp; strrstr</p>
<p>&nbsp;&nbsp;&nbsp; strspn find Find</p>
<p>&nbsp;&nbsp;&nbsp; 第一个匹配的值 fild_first_of FindOneOf</p>
<p>&nbsp;&nbsp;&nbsp; 从后面开始查找 ReserveFind</p>
<p>&nbsp;&nbsp;&nbsp; 指定匹配方式 find_if</p>
<p>&nbsp;&nbsp;&nbsp; 注：find_if中是把范围内的值挨个代入匹配函数直至返回true</p>
<p>&nbsp;&nbsp;&nbsp; b） 比较</p>
<p>&nbsp;&nbsp;&nbsp; 作用 char* string CString</p>
<p>&nbsp;&nbsp;&nbsp; 查找指定值（区分大小写） strcmp<br />
<table bordercolor="#cccccc" cellspacing="0" cellpadding="3" width="100%" bgcolor="#ffffff" border="2">
<tbody>
<tr>
<td>&nbsp;strncmp<br />strcoll<br />_strncoll operator&lt;<br />operator&gt;<br />operator&lt;=<br />operator&gt;=<br />operator==<br />operator!= Collate<br />Compare<br /></td></tr></tbody></table></p>
<p>&nbsp;&nbsp;&nbsp; 查找指定值（不区分大小写） _stricmp</p>
<p>&nbsp;&nbsp;&nbsp; _strnicmp</p>
<p>&nbsp;&nbsp;&nbsp; _stricoll</p>
<p>&nbsp;&nbsp;&nbsp; _strnicoll CollateNoCase</p>
<p>&nbsp;&nbsp;&nbsp; CompareNoCase</p>
<p>&nbsp;&nbsp;&nbsp; 注：返回值如果&lt;0则前面的值小于后面的值，反之亦然</p>
<p>&nbsp;&nbsp;&nbsp; c） 替换</p>
<p>&nbsp;&nbsp;&nbsp; 作用 char* string CString</p>
<p>&nbsp;&nbsp;&nbsp; 查找指定值 _strset<br />
<table bordercolor="#cccccc" cellspacing="0" cellpadding="3" width="100%" bgcolor="#ffffff" border="2">
<tbody>
<tr>
<td>&nbsp;_strnset replace<br />replace_copy<br />replace_copy_if<br />replace_if<br />Replace</td></tr></tbody></table></p>
<p>&nbsp;&nbsp;&nbsp; d） 插入</p>
<p>&nbsp;&nbsp;&nbsp; 作用 char* string CString</p>
<p>&nbsp;&nbsp;&nbsp; 查找指定值 insert Insert</p>
<p>&nbsp;&nbsp;&nbsp; e） 增加</p>
<p>&nbsp;&nbsp;&nbsp; 作用 char* string CString</p>
<p>&nbsp;&nbsp;&nbsp; 动态增加值 strcat push</p>
<p>&nbsp;&nbsp;&nbsp; append Append</p>
<p>&nbsp;&nbsp;&nbsp; AppendChar</p>
<p>&nbsp;&nbsp;&nbsp; AppendFormat</p>
<p>&nbsp;&nbsp;&nbsp; f） 截取</p>
<p>&nbsp;&nbsp;&nbsp; 作用 char* string CString</p>
<p>&nbsp;&nbsp;&nbsp; 得到部分值 用下标操作 substr Left</p>
<p>&nbsp;&nbsp;&nbsp; Mid</p>
<p>&nbsp;&nbsp;&nbsp; Right</p>
<p>&nbsp;&nbsp;&nbsp; Truncate</p>
<p>&nbsp;&nbsp;&nbsp; g） 移除</p>
<p>&nbsp;&nbsp;&nbsp; 作用 char* string CString</p>
<p>&nbsp;&nbsp;&nbsp; 移除部份值 remove Remove</p>
<p>&nbsp;&nbsp;&nbsp; 移除空白值 RemoveBlanks</p>
<p>&nbsp;&nbsp;&nbsp; 注：此为ATL提供，非C函数 remove_if Trim</p>
<p>&nbsp;&nbsp;&nbsp; TrimLeft</p>
<p>&nbsp;&nbsp;&nbsp; TrimRigth</p>
<p>&nbsp;&nbsp;&nbsp; h） 转换大小写</p>
<p>&nbsp;&nbsp;&nbsp; 作用 char* string CString</p>
<p>&nbsp;&nbsp;&nbsp; 转换大小写 _strlwr</p>
<p>&nbsp;&nbsp;&nbsp; _strupr MakeLower</p>
<p>&nbsp;&nbsp;&nbsp; MakeUpper</p>
<p>&nbsp;&nbsp;&nbsp; i） 与其他类型转换</p>
<p>&nbsp;&nbsp;&nbsp; 作用 char* string CString</p>
<p>&nbsp;&nbsp;&nbsp; 转化为数字 atoi</p>
<p>&nbsp;&nbsp;&nbsp; atod</p>
<p>&nbsp;&nbsp;&nbsp; atof Format</p>
<p>&nbsp;&nbsp;&nbsp; 转化为char* c_str GetBuffer</p>
<p>&nbsp;&nbsp;&nbsp; GetBufferSetLength</p>
<p>&nbsp;&nbsp;&nbsp; j） 格式化</p>
<p>&nbsp;&nbsp;&nbsp; 作用 char* string CString</p>
<p>&nbsp;&nbsp;&nbsp; 格式化 sprintf Format</p>
<p>&nbsp;&nbsp;&nbsp; k） 得到长度</p>
<p>&nbsp;&nbsp;&nbsp; 作用 char* string CString</p>
<p>&nbsp;&nbsp;&nbsp; 得到长度 strlen length GetLength</p>
<p>&nbsp;&nbsp;&nbsp; 得到大小 size GetAllocLength</p>
<p>&nbsp;&nbsp;&nbsp; l） 判断为空</p>
<p>&nbsp;&nbsp;&nbsp; 作用 char* string CString</p>
<p>&nbsp;&nbsp;&nbsp; 判断是否为空 判断是否==NULL或者第一个字符是否是&#8216;\0&#8217; empty IsEmpty</p>
<p>&nbsp;&nbsp;&nbsp; m） 重定义大小</p>
<p>&nbsp;&nbsp;&nbsp; 作用 char* string CString</p>
<p>&nbsp;&nbsp;&nbsp; 重定义大小 realloc</p>
<p>&nbsp;&nbsp;&nbsp; new resize GetBufferSetLength</p>
<p>&nbsp;&nbsp;&nbsp; n） 释放资源</p>
<p>&nbsp;&nbsp;&nbsp; 作用 char* string CString</p>
<p>&nbsp;&nbsp;&nbsp; 释放 free</p>
<p>&nbsp;&nbsp;&nbsp; delete （delete[]） ReleaseBuffer</p>
<p>&nbsp;&nbsp;&nbsp; ReleaseBufferSetLength</p>
<p>&nbsp;&nbsp;&nbsp; （五） <a class="channel_keylink" href="http://security.chinaitlab.com/" target="_blank">安全</a>性</p>
<p>&nbsp;&nbsp;&nbsp; CString &gt; string &gt; char*</p>
<p>&nbsp;&nbsp;&nbsp; （六） 灵活性</p>
<p>&nbsp;&nbsp;&nbsp; CString &gt; string &gt;char*</p>
<p>&nbsp;&nbsp;&nbsp; （七） 可移植性</p>
<p>&nbsp;&nbsp;&nbsp; char* = string &gt; CString</p>
<p>&nbsp;&nbsp;<strong>&nbsp; 总结</strong></p>
<p>&nbsp;&nbsp;&nbsp; 综上所述，在MFC、ATL中使用字符串尽量使用CString，毕竟都是微软的孩子，各方面都比其它更有优势，而在非微软平台上或对移植性要求较高的场合推荐使用string，标准模板库提供了那么强大的泛型算法，没必要再自己去造车轮。<br /><br /><br /><br />转换：<br /><br /></p>
<div class="blog_content">《C++标准函数库》中说的&nbsp; <br />有三个函数可以将字符串的内容转换为字符数组和C&#8212;string&nbsp; <br />1.data(),返回没有&#8221;\0&#8220;的字符串数组&nbsp; <br />2,c_str()，返回有&#8221;\0&#8220;的字符串数组&nbsp; <br />3，copy() <br />................................................................. <br />int 转 CString： <br />CString.Format("%d",int); <br />............................... <br />string 转 CString&nbsp; <br />CString.format("%s", string.c_str());&nbsp; <br />用c_str()确实比data()要好.&nbsp; <br />....................................... <br />char* 转 CString&nbsp; <br />CString.format("%s", char*);&nbsp; <br />CString strtest;&nbsp; <br />char * charpoint;&nbsp; <br />charpoint="give string a value";&nbsp; <br />strtest=charpoint; //直接付值 <br />................................................................... <br />CString 转 int <br />CString&nbsp; ss="1212.12";&nbsp; <br />int temp=atoi(ss); //atoi _atoi64或atol <br />&nbsp; <br />将字符转换为整数，可以使用atoi、_atoi64或atol。&nbsp; <br />int int_chage = atoi((lpcstr)ss) ; <br />或： <br />&nbsp;&nbsp; CString str = "23"; <br />&nbsp;&nbsp; UINT uint; <br />&nbsp;&nbsp; sscanf(str, "%d", uint); <br />.............................. <br />string 转 int <br />.............................. <br />char* 转 int <br />#include &lt;stdlib.h&gt; <br />&nbsp; <br />int atoi(const char *nptr); <br />long atol(const char *nptr); <br />long long atoll(const char *nptr); <br />long long atoq(const char *nptr); <br />................................................................... <br />CString 转 string <br />&nbsp; string s(CString.GetBuffer());&nbsp; <br />&nbsp; GetBuffer()后一定要ReleaseBuffer(),否则就没有释放缓冲区所占的空间.&nbsp; <br />.......................................... <br />int 转 string <br />.......................................... <br />char* 转 string&nbsp; <br />string s(char *);&nbsp; <br />你的只能初始化，在不是初始化的地方最好还是用assign(). <br />................................................................... <br />CString 转 char * <br />CString strtest="wwwwttttttt"; <br />charpoint=strtest.GetBuffer(strtest.GetLength()); <br />CString转换 char[100]&nbsp; <br />char a[100];&nbsp; <br />CString str("aaaaaa");&nbsp; <br />strncpy(a,(LPCTSTR)str,sizeof(a)); <br />&nbsp; CString&nbsp; str="aaa";&nbsp;&nbsp; <br />&nbsp; char*&nbsp; ch;&nbsp;&nbsp; <br />&nbsp; ch=(char*)(LPCTSTR)str; <br />.......................................... <br />int 转 char * <br />在stdlib.h中有个函数itoa() <br />itoa的用法： <br />itoa(i,num,10); <br />i 需要转换成字符的数字 <br />num 转换后保存字符的变量 <br />10 转换数字的基数（进制）10就是说按照10进制转换数字。还可以是2，8，16等等你喜欢的进制类型 <br />原形：char *itoa(int value, char* string, int radix); <br />实例： <br />#include "stdlib.h" <br />#include "stdio.h" <br />main() <br />{ <br />int i=1234; <br />char s[5]; <br />itoa(i,s,10); <br />printf("%s",s); <br />getchar(); <br />} <br />.......................................... <br />string 转 char *&nbsp; <br />char *p = string.c_str();&nbsp; <br /><br />string aa("aaa"); <br />char *c=aa.c_str(); <br />string mngName； <br />char t[200]; <br />memset(t,0,200); <br />strcpy(t,mngName.c_str()); <br />................................................................... <br />标准C里没有string,char *==char []==string <br />可以用CString.Format("%s",char *)这个方法来将char *转成CString。要把CString转成char *，用操 <br />作符（LPCSTR）CString就可以了。 <br />cannot convert from 'const char *' to 'char *' <br />const char *c=aa.c_str();&nbsp; <br />string.c_str()只能转换成const char * <br /></div>
<div class="blog_content">
<p align="left"><span style="font-size: 12pt; font-family: 宋体">String,CString,TCHAR,char</span><span style="font-size: 12pt; font-family: 宋体">之间区别和联系</span></p>
<p align="left"><span style="font-size: 12pt; font-family: 宋体">2008-07-25 19:53</span></p>
<table cellpadding="0" border="0">
<tbody>
<tr>
<td style="padding-right: 0.75pt; padding-left: 0.75pt; padding-bottom: 0.75pt; padding-top: 0.75pt">
<table style="width: 100%" cellspacing="0" cellpadding="0" width="100%" border="0">
<tbody>
<tr>
<td style="padding-right: 0cm; padding-left: 0cm; padding-bottom: 0cm; padding-top: 0cm">
<p style="text-align: left" align="left"><span style="font-size: 12pt; font-family: 宋体">char</span><span style="font-size: 12pt; font-family: 宋体">是类型<br /><span style="color: red">TCHAR</span><span style="color: red">也是！不过他可以通过是否定义了UNICODE宏来判断到底是<br />char还是w_char;</span></span></p></td></tr></tbody></table>
<p align="left"><span style="font-size: 12pt; font-family: 宋体">TCHAR</span><span style="font-size: 12pt; font-family: 宋体">是一种字符串类型，它让你在以MBCS和UNNICODE来build程序时可以使用同样的代码，不需要使用繁琐的宏定义来包含你的代码,而char代表ASCII的字符</span></p>
<p style="text-align: left" align="left"><span style="font-size: 12pt; font-family: 宋体">#ifdef UNICODE</span></p>
<p style="text-align: left" align="left"><span style="font-size: 12pt; font-family: 宋体">&nbsp;&nbsp; typedef wchar_t TCHAR;</span></p>
<p style="text-align: left" align="left"><span style="font-size: 12pt; font-family: 宋体">&nbsp;&nbsp; #else</span></p>
<p style="text-align: left" align="left"><span style="font-size: 12pt; font-family: 宋体">&nbsp;&nbsp; typedef char TCHAR;</span></p>
<p style="text-align: left" align="left"><span style="font-size: 12pt; font-family: 宋体">&nbsp;&nbsp; #endif</span></p>
<p align="left"><span style="font-size: 12pt; font-family: 宋体">所以用MBCS来build时，TCHAR是char，使用UNICODE时，TCHAR是wchar_t.</span></p>
<p align="left"><span style="font-size: 12pt; font-family: 宋体"><br /></span><span style="font-size: 12pt; font-family: 宋体">至于String,CString他们都是一种封装了字串处理的操作！<br />你可以打开他们的源代码找寻究竟！</span></p>
<p align="left"><span style="font-size: 12pt; font-family: 宋体"><br />CString</span><span style="font-size: 12pt; font-family: 宋体">属于VC的类库<br /><br />string是标准C++的类库<br /><br />string.h是C的库函数。<br /><br />研究它们的源代好些！</span></p>
<p align="left"><span style="font-size: 12pt; font-family: 宋体">TCHAR,char</span><span style="font-size: 12pt; font-family: 宋体">是可以同整型互换的类型。<br />String,CString代表了一块内存区域。</span></p>
<p align="left"><span style="font-size: 12pt; font-family: 宋体">TCHAR </span><span style="font-size: 12pt; font-family: 宋体">赋值</span></p>
<p align="left"><span style="font-size: 12pt; font-family: 宋体">#include &lt;tchar.h&gt;</span></p>
<p align="left"><span style="font-size: 12pt; font-family: 宋体">TCHAR szWindowText[256]=_T("QQ2006");</span></p>
<p align="left"><span style="font-size: 12pt; font-family: 宋体">char*</span><span style="font-size: 12pt; font-family: 宋体">、TCHAR*转换CString <br />CString str(****) <br />下面详细写一下其它转换 <br />////////////////////////////// <br />/* <br />*********************************************************************** <br />* 函数： TransCStringToTCHAR <br />* 描述：将CString 转换为 TCHAR* <br />* 日期：<br />*********************************************************************** <br />*/ <br />TCHAR* CPublic::CString2TCHAR(CString &amp;str) <br />{ <br />int iLen = str.GetLength(); <br />TCHAR* szRs = new TCHAR[iLen]; <br />lstrcpy(szRs, str.GetBuffer(iLen)); <br />str.ReleaseBuffer(); <br />return szRs; <br />} <br /><br />/* <br />*********************************************************************** <br />* 函数： THCAR2Char <br />* 描述：将TCHAR* 转换为 char* <br />* 日期：</span></p>
<p align="left"><span style="font-size: 12pt; font-family: 宋体">*********************************************************************** <br />*/ <br />char* CPublic::THCAR2char(TCHAR* tchStr) <br />{ <br />int iLen = 2*wcslen(tchStr);//CString,TCHAR</span><span style="font-size: 12pt; font-family: 宋体">汉字算一个字符，因此不用普通计算长度 <br />char* chRtn = new char[iLen+1] <br />wcstombs(chRtn,tchStr,iLen+1);//转换成功返回为非负值 <br />return chRtn; <br />} <br /><br />/* <br />*********************************************************************** <br />* 函数： CString2char <br />* 描述：将CString转换为 char* <br />* 日期：<br />*********************************************************************** <br />*/ <br />char* CPublic::CString2char(CString &amp;str) <br />{ <br />int len = str.GetLength(); <br />char* chRtn = (char*)malloc((len*2+1)*sizeof(char));//CString的长度中汉字算一个长度 <br />memset(chRtn, 0, 2*len+1); <br />USES_CONVERSION; <br />strcpy((LPSTR)chRtn,OLE2A(str.LockBuffer())); <br />return chRtn; <br />} <br />//参考 <br />/////////////////////// <br />//Pocket PC上的UNICODE和ANSI字符串 <br /><br />//By Vassili Philippov, September 26, 2001. <br /><br />//杨方思歧 译 <br />//////////////////////// <br />/* <br />*********************************************************************** <br />* 函 数 名：GetAnsiString <br />* 描 述：将CString（unicode）转换为char*(ANSI) <br />* 参 数：CString &amp;s 要转换的CString <br />* 返 回 值：返回转换结果 <br />* 创建日期：</span></p>
<p align="left"><span style="font-size: 12pt; font-family: 宋体">* </span><span style="font-size: 12pt; font-family: 宋体">最后修改：<br />*********************************************************************** <br />*/ <br />char* GetAnsiString(const CString &amp;s) <br />{ <br />int nSize = 2*s.GetLength(); <br />char *pAnsiString = new char[nSize+1]; <br />wcstombs(pAnsiString, s, nSize+1); <br />return pAnsiString; <br />} <br /><br /></span></p></td></tr></tbody></table></div>
<p>&nbsp;</p><img src ="http://www.cppblog.com/strawberry/aggbug/168241.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/strawberry/" target="_blank">futual</a> 2012-03-18 11:38 <a href="http://www.cppblog.com/strawberry/articles/168241.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>