﻿<?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++博客-chenjt3533-随笔分类-C/C++</title><link>http://www.cppblog.com/chenjt3533/category/20401.html</link><description>&lt;script type="text/javascript" charset="UTF-8" src="http://www.yulu.info/javascript.asp"&gt;&lt;/script&gt;
&lt;p&gt;&lt;/p&gt;</description><language>zh-cn</language><lastBuildDate>Sat, 13 Sep 2014 08:40:56 GMT</lastBuildDate><pubDate>Sat, 13 Sep 2014 08:40:56 GMT</pubDate><ttl>60</ttl><item><title>从Graphics 中获取Bitmap图像</title><link>http://www.cppblog.com/chenjt3533/archive/2014/09/12/208285.html</link><dc:creator>chenjt3533</dc:creator><author>chenjt3533</author><pubDate>Fri, 12 Sep 2014 08:36:00 GMT</pubDate><guid>http://www.cppblog.com/chenjt3533/archive/2014/09/12/208285.html</guid><wfw:comment>http://www.cppblog.com/chenjt3533/comments/208285.html</wfw:comment><comments>http://www.cppblog.com/chenjt3533/archive/2014/09/12/208285.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chenjt3533/comments/commentRss/208285.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenjt3533/services/trackbacks/208285.html</trackback:ping><description><![CDATA[<div><span style="white-space:pre">	</span>CDC dcTmp;<span style="white-space:pre">	</span></div><div><span style="white-space:pre">	</span>HDC hDc= graph.GetHDC(); /// &lt;会被加锁&gt;</div><div><span style="white-space:pre">	</span>dcTmp.Attach(hDc);</div><div><span style="white-space:pre">	</span>CBitmap *pBmp = dcTmp.GetCurrentBitmap();</div><div><span style="white-space:pre">	</span>HBITMAP hBITMAP = (HBITMAP)pBmp-&gt;GetSafeHandle();</div><div><span style="white-space:pre">	</span>Bitmap bitmap(hBITMAP, 0);<span style="white-space: pre;">	</span></div><div><span style="white-space:pre">	</span>dcTmp.Detach(); /// &lt;释放&gt;</div><div><span style="white-space:pre">	</span>graph.ReleaseHDC(hDc); /// &lt;解锁&gt;</div><img src ="http://www.cppblog.com/chenjt3533/aggbug/208285.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenjt3533/" target="_blank">chenjt3533</a> 2014-09-12 16:36 <a href="http://www.cppblog.com/chenjt3533/archive/2014/09/12/208285.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>获取农历年、时辰</title><link>http://www.cppblog.com/chenjt3533/archive/2014/08/26/208145.html</link><dc:creator>chenjt3533</dc:creator><author>chenjt3533</author><pubDate>Tue, 26 Aug 2014 15:28:00 GMT</pubDate><guid>http://www.cppblog.com/chenjt3533/archive/2014/08/26/208145.html</guid><wfw:comment>http://www.cppblog.com/chenjt3533/comments/208145.html</wfw:comment><comments>http://www.cppblog.com/chenjt3533/archive/2014/08/26/208145.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chenjt3533/comments/commentRss/208145.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenjt3533/services/trackbacks/208145.html</trackback:ping><description><![CDATA[<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><br /><span style="color: #0000FF; ">void</span>&nbsp;CCalendar::FormatLunarYear(WORD&nbsp;iYear,&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;pBuffer)<br />{&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;szText1[]&nbsp;=&nbsp;"甲乙丙丁戊己庚辛壬癸";<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;szText2[]&nbsp;=&nbsp;"子丑寅卯辰巳午未申酉戌亥";<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;szText3[]&nbsp;=&nbsp;"鼠牛虎免龙蛇马羊猴鸡狗猪";<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;memcpy(pBuffer,&nbsp;&nbsp;&nbsp;szText1+((iYear-4)%10)*2,&nbsp;2);<br />&nbsp;&nbsp;&nbsp;&nbsp;memcpy(pBuffer+2,&nbsp;szText2+((iYear-4)%12)*2,&nbsp;2);<br />&nbsp;&nbsp;&nbsp;&nbsp;pBuffer[4]='&nbsp;';<br />&nbsp;&nbsp;&nbsp;&nbsp;memcpy(pBuffer+5,&nbsp;szText3+((iYear-4)%12)*2,&nbsp;2);<br />&nbsp;&nbsp;&nbsp;&nbsp;strcpy(pBuffer+7,&nbsp;"年");<br />}<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;CCalendar::FormatLunarHour(WORD&nbsp;iHour,&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;*pBuffer)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;szText[]&nbsp;=&nbsp;"子丑寅卯辰巳午未申酉戌亥";<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;nIndex&nbsp;=&nbsp;(iHour&nbsp;+&nbsp;1)&nbsp;/&nbsp;2;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(12&nbsp;==&nbsp;nIndex&nbsp;&amp;&amp;&nbsp;23&nbsp;==&nbsp;iHour)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nIndex&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;memcpy(pBuffer,&nbsp;szText+nIndex*2,&nbsp;2);<br />&nbsp;&nbsp;&nbsp;&nbsp;strcpy(pBuffer+2,&nbsp;"时");<br />}</div><img src ="http://www.cppblog.com/chenjt3533/aggbug/208145.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenjt3533/" target="_blank">chenjt3533</a> 2014-08-26 23:28 <a href="http://www.cppblog.com/chenjt3533/archive/2014/08/26/208145.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ffplay 将视频帧转换成bmp图片</title><link>http://www.cppblog.com/chenjt3533/archive/2014/08/21/208083.html</link><dc:creator>chenjt3533</dc:creator><author>chenjt3533</author><pubDate>Thu, 21 Aug 2014 14:21:00 GMT</pubDate><guid>http://www.cppblog.com/chenjt3533/archive/2014/08/21/208083.html</guid><wfw:comment>http://www.cppblog.com/chenjt3533/comments/208083.html</wfw:comment><comments>http://www.cppblog.com/chenjt3533/archive/2014/08/21/208083.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chenjt3533/comments/commentRss/208083.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenjt3533/services/trackbacks/208083.html</trackback:ping><description><![CDATA[<div><div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;video_thread2(<span style="color: #0000FF; ">void</span>&nbsp;*arg)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;AVPacket&nbsp;pkt&nbsp;=&nbsp;{&nbsp;0&nbsp;};<br />&nbsp;&nbsp;&nbsp;&nbsp;VideoState&nbsp;*<span style="color: #0000FF; ">is</span>&nbsp;=&nbsp;(VideoState&nbsp;*)arg;<br />&nbsp;&nbsp;&nbsp;&nbsp;AVFrame&nbsp;*pFrame&nbsp;=&nbsp;avcodec_alloc_frame();<br />&nbsp;&nbsp;&nbsp;&nbsp;int64_t&nbsp;pts_int&nbsp;=&nbsp;AV_NOPTS_VALUE,&nbsp;pos&nbsp;=&nbsp;-1;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">double</span>&nbsp;pts;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;ret;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(;;)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(<span style="color: #0000FF; ">is</span>-&gt;paused&nbsp;&amp;&amp;&nbsp;!<span style="color: #0000FF; ">is</span>-&gt;videoq.abort_request)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SDL_Delay(10);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;avcodec_get_frame_defaults(pFrame);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;av_free_packet(&amp;pkt);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;=&nbsp;get_video_frame(<span style="color: #0000FF; ">is</span>,&nbsp;pFrame,&nbsp;&amp;pts_int,&nbsp;&amp;pkt);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(ret&nbsp;&lt;&nbsp;0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">goto</span>&nbsp;the_end;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(!ret)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">continue</span>;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pts&nbsp;=&nbsp;pts_int&nbsp;*&nbsp;av_q2d(<span style="color: #0000FF; ">is</span>-&gt;video_st-&gt;time_base);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;=&nbsp;queue_picture(<span style="color: #0000FF; ">is</span>,&nbsp;pFrame,&nbsp;pts,&nbsp;pkt.pos);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(ret&nbsp;&lt;&nbsp;0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">goto</span>&nbsp;the_end;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(<span style="color: #0000FF; ">is</span>-&gt;step)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stream_toggle_pause(<span style="color: #0000FF; ">is</span>);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;nWidth&nbsp;=&nbsp;pFrame-&gt;width;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;nHeight&nbsp;=&nbsp;pFrame-&gt;height;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AVPixelFormat&nbsp;srcfmt&nbsp;=&nbsp;(AVPixelFormat)pFrame-&gt;format;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AVPixelFormat&nbsp;dstfmt&nbsp;=&nbsp;AV_PIX_FMT_BGR24;<span style="color: #008000; ">//</span><span style="color: #008000; ">AV_PIX_FMT_RGB24;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">AV_PIX_FMT_BGR24;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AVFrame&nbsp;*pFrameRGB;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pFrameRGB&nbsp;=&nbsp;avcodec_alloc_frame();<br /><br /><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;src_bytes_num&nbsp;=&nbsp;avpicture_get_size(srcfmt,&nbsp;nWidth,&nbsp;nHeight);<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint8_t*&nbsp;src_buff&nbsp;=&nbsp;(uint8_t*)av_malloc(src_bytes_num);<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;avpicture_fill((AVPicture*)pFrame,&nbsp;src_buff,&nbsp;srcfmt,&nbsp;nWidth,&nbsp;nHeight);</span><span style="color: #008000; "><br /></span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;dst_bytes_num&nbsp;=&nbsp;avpicture_get_size(dstfmt,&nbsp;nWidth,&nbsp;nHeight);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint8_t*&nbsp;dst_buff&nbsp;=&nbsp;(uint8_t*)av_malloc(dst_bytes_num);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;avpicture_fill((AVPicture*)pFrameRGB,&nbsp;dst_buff,&nbsp;dstfmt,&nbsp;nWidth,&nbsp;nHeight);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SwsContext*&nbsp;pSwsCtx&nbsp;=&nbsp;sws_getContext(nWidth,&nbsp;nHeight,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;srcfmt,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nWidth,&nbsp;nHeight,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dstfmt,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SWS_BICUBIC,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NULL,NULL,NULL);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080; ">///</span><span style="color: #008000; ">&nbsp;</span><span style="color: #808080; ">&lt;转换图像格式&gt;</span><span style="color: #808080; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sws_scale(pSwsCtx,&nbsp;pFrame-&gt;data,&nbsp;pFrame-&gt;linesize,&nbsp;0,&nbsp;nHeight,&nbsp;pFrameRGB-&gt;data,&nbsp;pFrameRGB-&gt;linesize);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;nnn&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;((nnn++&nbsp;%&nbsp;5)&nbsp;==&nbsp;0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">saveAsBitmap(pFrameRGB,&nbsp;nWidth,&nbsp;nHeight,&nbsp;nnn);</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />the_end:<br />&nbsp;&nbsp;&nbsp;&nbsp;avcodec_flush_buffers(<span style="color: #0000FF; ">is</span>-&gt;video_st-&gt;codec);<br />&nbsp;&nbsp;&nbsp;&nbsp;av_free_packet(&amp;pkt);<br />&nbsp;&nbsp;&nbsp;&nbsp;avcodec_free_frame(&amp;pFrame);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />}<br /><br /><br /><span style="color: #0000FF; ">bool</span>&nbsp;saveAsBitmap(AVFrame&nbsp;*pFrameRGB,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;width,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;height,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;iFrame)&nbsp;&nbsp;<br />{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(NULL&nbsp;==&nbsp;pFrameRGB-&gt;data[0])<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">false</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;FILE&nbsp;*pFile&nbsp;=&nbsp;NULL;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;BITMAPFILEHEADER&nbsp;bmpheader;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;BITMAPINFO&nbsp;bmpinfo;&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;fileName[32];&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;bpp&nbsp;=&nbsp;24;&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;open&nbsp;file&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;sprintf(fileName,&nbsp;"./images/frame%d.bmp",&nbsp;iFrame);&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;pFile&nbsp;=&nbsp;fopen(fileName,&nbsp;"wb");&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(!pFile)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">false</span>;&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;bmpheader.bfType&nbsp;=&nbsp;('M'&nbsp;&lt;&lt;8)|'B';&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;bmpheader.bfReserved1&nbsp;=&nbsp;0;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;bmpheader.bfReserved2&nbsp;=&nbsp;0;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;bmpheader.bfOffBits&nbsp;=&nbsp;<span style="color: #0000FF; ">sizeof</span>(BITMAPFILEHEADER)&nbsp;+&nbsp;<span style="color: #0000FF; ">sizeof</span>(BITMAPINFOHEADER);&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;bmpheader.bfSize&nbsp;=&nbsp;bmpheader.bfOffBits&nbsp;+&nbsp;width*height*bpp/8;&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;bmpinfo.bmiHeader.biSize&nbsp;=&nbsp;<span style="color: #0000FF; ">sizeof</span>(BITMAPINFOHEADER);&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;bmpinfo.bmiHeader.biWidth&nbsp;=&nbsp;width;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;bmpinfo.bmiHeader.biHeight&nbsp;=&nbsp;-height;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">reverse&nbsp;the&nbsp;image&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;bmpinfo.bmiHeader.biPlanes&nbsp;=&nbsp;1;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;bmpinfo.bmiHeader.biBitCount&nbsp;=&nbsp;bpp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;bmpinfo.bmiHeader.biCompression&nbsp;=&nbsp;BI_RGB;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;bmpinfo.bmiHeader.biSizeImage&nbsp;=&nbsp;0;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;bmpinfo.bmiHeader.biXPelsPerMeter&nbsp;=&nbsp;100;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;bmpinfo.bmiHeader.biYPelsPerMeter&nbsp;=&nbsp;100;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;bmpinfo.bmiHeader.biClrUsed&nbsp;=&nbsp;0;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;bmpinfo.bmiHeader.biClrImportant&nbsp;=&nbsp;0;&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;fwrite(&amp;bmpheader,&nbsp;<span style="color: #0000FF; ">sizeof</span>(BITMAPFILEHEADER),&nbsp;1,&nbsp;pFile);&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;fwrite(&amp;bmpinfo.bmiHeader,&nbsp;<span style="color: #0000FF; ">sizeof</span>(BITMAPINFOHEADER),&nbsp;1,&nbsp;pFile);&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint8_t&nbsp;*buffer&nbsp;=&nbsp;pFrameRGB-&gt;data[0];&nbsp;&nbsp;<br /><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;h=0;&nbsp;h&lt;height;&nbsp;h++)&nbsp;&nbsp;<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;w=0;&nbsp;w&lt;width;&nbsp;w++)&nbsp;&nbsp;<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fwrite(buffer+2,&nbsp;1,&nbsp;1,&nbsp;pFile);&nbsp;&nbsp;<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fwrite(buffer+1,&nbsp;1,&nbsp;1,&nbsp;pFile);&nbsp;&nbsp;<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fwrite(buffer,&nbsp;1,&nbsp;1,&nbsp;pFile);&nbsp;&nbsp;<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buffer&nbsp;+=&nbsp;3;&nbsp;&nbsp;<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span><br />&nbsp;&nbsp;&nbsp;&nbsp;fwrite(buffer,width*height*bpp/8,1,pFile);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;fclose(pFile);&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">true</span>;&nbsp;&nbsp;<br />}&nbsp;</div></div></div><img src ="http://www.cppblog.com/chenjt3533/aggbug/208083.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenjt3533/" target="_blank">chenjt3533</a> 2014-08-21 22:21 <a href="http://www.cppblog.com/chenjt3533/archive/2014/08/21/208083.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c++ 获取汉字首字母</title><link>http://www.cppblog.com/chenjt3533/archive/2013/05/31/200716.html</link><dc:creator>chenjt3533</dc:creator><author>chenjt3533</author><pubDate>Fri, 31 May 2013 05:01:00 GMT</pubDate><guid>http://www.cppblog.com/chenjt3533/archive/2013/05/31/200716.html</guid><wfw:comment>http://www.cppblog.com/chenjt3533/comments/200716.html</wfw:comment><comments>http://www.cppblog.com/chenjt3533/archive/2013/05/31/200716.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chenjt3533/comments/commentRss/200716.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenjt3533/services/trackbacks/200716.html</trackback:ping><description><![CDATA[<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"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="color: #000000"><br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />#include&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">iostream</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />#include&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">string</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">namespace</span><span style="color: #000000">&nbsp;std;<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">#define</span><span style="color: #000000">&nbsp;CONVERT(start,&nbsp;end,&nbsp;code,&nbsp;letter)&nbsp;if(code&nbsp;&gt;=&nbsp;start&nbsp;&amp;&amp;&nbsp;code&nbsp;&lt;=&nbsp;end)&nbsp;return&nbsp;letter</span><span style="color: #000000"><br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;Convert(wchar_t&nbsp;n)<br /><img id="Codehighlighter1_175_993_Open_Image" onclick="this.style.display='none'; Codehighlighter1_175_993_Open_Text.style.display='none'; Codehighlighter1_175_993_Closed_Image.style.display='inline'; Codehighlighter1_175_993_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img id="Codehighlighter1_175_993_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_175_993_Closed_Text.style.display='none'; Codehighlighter1_175_993_Open_Image.style.display='inline'; Codehighlighter1_175_993_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top"></span><span id="Codehighlighter1_175_993_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 alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_175_993_Open_Text"><span style="color: #000000">{<br /><img id="Codehighlighter1_178_195_Open_Image" onclick="this.style.display='none'; Codehighlighter1_178_195_Open_Text.style.display='none'; Codehighlighter1_178_195_Closed_Image.style.display='inline'; Codehighlighter1_178_195_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_178_195_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_178_195_Closed_Text.style.display='none'; Codehighlighter1_178_195_Open_Image.style.display='inline'; Codehighlighter1_178_195_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_178_195_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">/**/</span><span id="Codehighlighter1_178_195_Open_Text"><span style="color: #808080">///</span><span style="color: #008000">&nbsp;根据汉字区域码获取拼音声母</span><span style="color: #808080"></span></span><br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xB0A1</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xB0C4</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">a</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0XB0C5</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0XB2C0</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">b</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xB2C1</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xB4ED</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">c</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xB4EE</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xB6E9</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">d</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xB6EA</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xB7A1</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">e</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xB7A2</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xB8c0</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">f</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xB8C1</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xB9FD</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">g</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xB9FE</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xBBF6</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">h</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xBBF7</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xBFA5</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">j</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xBFA6</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xC0AB</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">k</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xC0AC</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xC2E7</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">l</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xC2E8</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xC4C2</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">m</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xC4C3</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xC5B5</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">n</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xC5B6</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xC5BD</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">o</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xC5BE</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xC6D9</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">p</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xC6DA</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xC8BA</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">q</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xC8BB</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xC8F5</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">r</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xC8F6</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xCBF0</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">s</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xCBFA</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xCDD9</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">t</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xCDDA</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xCEF3</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">w</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xCEF4</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xD188</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">x</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xD1B9</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xD4D0</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">y</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;CONVERT(</span><span style="color: #000000">0xD4D1</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0xD7F9</span><span style="color: #000000">,&nbsp;n,&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">z</span><span style="color: #000000">'</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">\0</span><span style="color: #000000">'</span><span style="color: #000000">;<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000"><br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;Test_Invert()<br /><img id="Codehighlighter1_1015_1408_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1015_1408_Open_Text.style.display='none'; Codehighlighter1_1015_1408_Closed_Image.style.display='inline'; Codehighlighter1_1015_1408_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img id="Codehighlighter1_1015_1408_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1015_1408_Closed_Text.style.display='none'; Codehighlighter1_1015_1408_Open_Image.style.display='inline'; Codehighlighter1_1015_1408_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top"></span><span id="Codehighlighter1_1015_1408_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 alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_1015_1408_Open_Text"><span style="color: #000000">{<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;sChinese&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">根据汉字区域码获取汉字首字母</span><span style="color: #000000">"</span><span style="color: #000000">;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;输入汉字</span><span style="color: #008000"><br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000"><br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;wchar_t&nbsp;wchr&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;nCount&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;sChinese.length()&nbsp;</span><span style="color: #000000">/</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">2</span><span style="color: #000000">;<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;buff&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">[nCount];<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;memset(buff,&nbsp;</span><span style="color: #000000">0x00</span><span style="color: #000000">,&nbsp;</span><span style="color: #0000ff">sizeof</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">nCount</span><span style="color: #000000">+</span><span style="color: #000000">1</span><span style="color: #000000">);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">,&nbsp;j&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;i&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;nCount;&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">i)<br /><img id="Codehighlighter1_1238_1355_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1238_1355_Open_Text.style.display='none'; Codehighlighter1_1238_1355_Closed_Image.style.display='inline'; Codehighlighter1_1238_1355_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_1238_1355_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1238_1355_Closed_Text.style.display='none'; Codehighlighter1_1238_1355_Open_Image.style.display='inline'; Codehighlighter1_1238_1355_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_1238_1355_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 alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_1238_1355_Open_Text"><span style="color: #000000">{<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wchr&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(sChinese[j</span><span style="color: #000000">++</span><span style="color: #000000">]&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0xff</span><span style="color: #000000">)&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">8</span><span style="color: #000000">;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;高字节</span><span style="color: #008000"><br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wchr&nbsp;</span><span style="color: #000000">|=</span><span style="color: #000000">&nbsp;(sChinese[j</span><span style="color: #000000">++</span><span style="color: #000000">]&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0xff</span><span style="color: #000000">);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;低字节</span><span style="color: #008000"><br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buff[i]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;Convert(wchr);<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">pin&nbsp;yin&nbsp;=&nbsp;[&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;buff&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;]</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;endl;&nbsp;<br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000"><br /><img alt="" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span></div><br /><img height="61" alt="" src="http://www.cppblog.com/images/cppblog_com/chenjt3533/reulst.jpg" width="283" border="0" longdesc="" /><br /><br /><br /><br /><img src ="http://www.cppblog.com/chenjt3533/aggbug/200716.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenjt3533/" target="_blank">chenjt3533</a> 2013-05-31 13:01 <a href="http://www.cppblog.com/chenjt3533/archive/2013/05/31/200716.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《c Templates 》笔记</title><link>http://www.cppblog.com/chenjt3533/archive/2013/05/30/200696.html</link><dc:creator>chenjt3533</dc:creator><author>chenjt3533</author><pubDate>Thu, 30 May 2013 07:36:00 GMT</pubDate><guid>http://www.cppblog.com/chenjt3533/archive/2013/05/30/200696.html</guid><wfw:comment>http://www.cppblog.com/chenjt3533/comments/200696.html</wfw:comment><comments>http://www.cppblog.com/chenjt3533/archive/2013/05/30/200696.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chenjt3533/comments/commentRss/200696.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenjt3533/services/trackbacks/200696.html</trackback:ping><description><![CDATA[<p>1、Function Templates(函数模版)</p>
<p>例：<br />tempalte &lt;typename T&gt;<br />T GetMax(T a, T b)<br />{<br />&nbsp;return a &lt; b ? b : a;<br />}</p>
<p>/// 重载<br />tempalte &lt;typename T&gt;<br />T GetMax(T a, T b, T c)<br />{<br />&nbsp;return (c &lt; GetMax(a, b) ? GetMax(a, b) : c);<br />}</p>
<p>/// 默认类型<br />template &lt;typename T=int&gt;<br />T GetMax(T a, T b)<br />{<br />&nbsp;retrun a &lt; b ? b : a;<br />}</p>
<p>2、Class Templates(类模版)<br />例：<br />template &lt;typename T&gt;<br />class MyStack<br />{<br />&nbsp;friend class CFriend1;&nbsp;&nbsp; // 普通友元类不需要先申明<br />&nbsp;friend class CFriend2&lt;T&gt;; // error, 友元模板类必须先申明</p>
<p>&nbsp;public:<br />&nbsp;&nbsp;void Push(T const&amp;);<br />&nbsp;&nbsp;void Pop();<br />&nbsp;&nbsp;T Top() const;<br />&nbsp;&nbsp;bool Empty() const;<br />&nbsp;private:<br />&nbsp;&nbsp;std::vector&lt;T&gt; elems;<br />};</p>
<p>void MyStack&lt;T&gt;::Push(T const&amp; e)<br />{<br />&nbsp;elems.push_back(e);<br />}</p>
<p>/// 继承<br />template &lt;typename T&gt;<br />class Derived : public MyStack&lt;T&gt;<br />{<br />public:<br />&nbsp;void Test()<br />&nbsp;{<br />&nbsp;&nbsp;Top(); // 应该使用this-&gt;Top() 或 MyStack&lt;T&gt;::Top(), 否则就调用外部Top()，或者编译错误<br />&nbsp;}</p>
<p>&nbsp;/// 成员模版函数，不能是virtual<br />&nbsp;template &lt;typename T2&gt;<br />&nbsp;void Test2()<br />&nbsp;{<br />&nbsp;&nbsp;<br />&nbsp;}<br />};</p>
<p><br />3、NonType Templates(非类型模版参数)<br />局限性：通常只能是常数整数(包括enum)和指向局部变量的指针。<br />例:<br />template &lt;typename T, int MAXSIZE&gt;<br />struct NonTypeStruct<br />{<br />&nbsp;T elems[MAXSIZE];<br />};</p>
<p><br />4、typename 关键字<br />typename是在C++标准化工程中被引入的，目的是向编译器说明template内部的某个表示符号是个类型。<br />例：<br />template&lt;typename T&gt;<br />struct MyStruct<br />{<br />&nbsp;typename T::SubType* m_Ptr; // 表示m_Ptr是指向SubType是T内部类型的一个指针，若没有typename，就表</p>
<p>示T的静态变量SubType乘以m_Ptr。<br />};</p>
<p>5、双重模版参数<br />例：<br />template &lt;typename T, template &lt;typename&gt; class CT&gt;<br />class DoubleTemplate<br />{<br />&nbsp;CT&lt;t&gt; m_ct;&nbsp;<br />};<br />DoubleTemplate&lt;int, std::vector&gt; dbTemplate; // 类中定义了一个vector&lt;int&gt;的成员属性m_ct;</p>
<p>6、模板的申明和定义必须在同一个文档中，否则会出现连接错误<br />例：<br />// Test.h<br />template &lt;typename T&gt;<br />T Max(T a);</p>
<p>// Test.cpp<br />template &lt;typename T&gt;<br />T Max(T a) { return a; }</p>
<p>// Main.cpp<br />#include "Test.h"</p>
<p>void main()<br />{<br />&nbsp;int a = Max&lt;int&gt;(1); // error LNK2019，除非同时 #inclde "test.cpp"<br />}</p>
<p>7、模版类不能和其它不同类型的实体同名。<br />例：<br />int c;<br />class c; // ok，普通类可以<br />template &lt;typename T&gt;<br />class c; // error，模板类不行</p>
<p>8、在类中声明友元模版类<br />例：<br />class Manager<br />{<br />&nbsp;template &lt;typename T&gt;<br />&nbsp;friend class Task;<br />};</p>
<p>9、看看小细节<br />例：<br />template &lt;bool b&gt;<br />class Invert<br />{<br />&nbsp;public:<br />&nbsp;&nbsp;static bool const result = !b;<br />};<br />bool bTest = Invert&lt;(1&gt;0)&gt;::result; // (1&gt;0)小括号必须存在</p>
<p>std::vector&lt;std::list&lt;int&gt; &gt; vectList; // &lt;std::list&lt;int&gt; &gt;空格必须存在</p><img src ="http://www.cppblog.com/chenjt3533/aggbug/200696.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenjt3533/" target="_blank">chenjt3533</a> 2013-05-30 15:36 <a href="http://www.cppblog.com/chenjt3533/archive/2013/05/30/200696.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++模板简单分析与举例</title><link>http://www.cppblog.com/chenjt3533/archive/2013/03/30/198947.html</link><dc:creator>chenjt3533</dc:creator><author>chenjt3533</author><pubDate>Sat, 30 Mar 2013 06:23:00 GMT</pubDate><guid>http://www.cppblog.com/chenjt3533/archive/2013/03/30/198947.html</guid><wfw:comment>http://www.cppblog.com/chenjt3533/comments/198947.html</wfw:comment><comments>http://www.cppblog.com/chenjt3533/archive/2013/03/30/198947.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chenjt3533/comments/commentRss/198947.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenjt3533/services/trackbacks/198947.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->#pragma&nbsp;once#include&nbsp;&lt;iostream&gt;/**//*/////////////////////////////////////////////&nbs...&nbsp;&nbsp;<a href='http://www.cppblog.com/chenjt3533/archive/2013/03/30/198947.html'>阅读全文</a><img src ="http://www.cppblog.com/chenjt3533/aggbug/198947.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenjt3533/" target="_blank">chenjt3533</a> 2013-03-30 14:23 <a href="http://www.cppblog.com/chenjt3533/archive/2013/03/30/198947.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>四种查找算法的简单分析与实现</title><link>http://www.cppblog.com/chenjt3533/archive/2013/03/28/198899.html</link><dc:creator>chenjt3533</dc:creator><author>chenjt3533</author><pubDate>Thu, 28 Mar 2013 11:57:00 GMT</pubDate><guid>http://www.cppblog.com/chenjt3533/archive/2013/03/28/198899.html</guid><wfw:comment>http://www.cppblog.com/chenjt3533/comments/198899.html</wfw:comment><comments>http://www.cppblog.com/chenjt3533/archive/2013/03/28/198899.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chenjt3533/comments/commentRss/198899.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenjt3533/services/trackbacks/198899.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->#pragma&nbsp;once/**//*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&...&nbsp;&nbsp;<a href='http://www.cppblog.com/chenjt3533/archive/2013/03/28/198899.html'>阅读全文</a><img src ="http://www.cppblog.com/chenjt3533/aggbug/198899.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenjt3533/" target="_blank">chenjt3533</a> 2013-03-28 19:57 <a href="http://www.cppblog.com/chenjt3533/archive/2013/03/28/198899.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>七种排序算法的简单分析与实现</title><link>http://www.cppblog.com/chenjt3533/archive/2013/03/25/198815.html</link><dc:creator>chenjt3533</dc:creator><author>chenjt3533</author><pubDate>Mon, 25 Mar 2013 13:01:00 GMT</pubDate><guid>http://www.cppblog.com/chenjt3533/archive/2013/03/25/198815.html</guid><wfw:comment>http://www.cppblog.com/chenjt3533/comments/198815.html</wfw:comment><comments>http://www.cppblog.com/chenjt3533/archive/2013/03/25/198815.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/chenjt3533/comments/commentRss/198815.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenjt3533/services/trackbacks/198815.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->#pragma&nbsp;once/**//**//**//*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp...&nbsp;&nbsp;<a href='http://www.cppblog.com/chenjt3533/archive/2013/03/25/198815.html'>阅读全文</a><img src ="http://www.cppblog.com/chenjt3533/aggbug/198815.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenjt3533/" target="_blank">chenjt3533</a> 2013-03-25 21:01 <a href="http://www.cppblog.com/chenjt3533/archive/2013/03/25/198815.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>KMP 匹配算法</title><link>http://www.cppblog.com/chenjt3533/archive/2013/03/20/198641.html</link><dc:creator>chenjt3533</dc:creator><author>chenjt3533</author><pubDate>Wed, 20 Mar 2013 11:06:00 GMT</pubDate><guid>http://www.cppblog.com/chenjt3533/archive/2013/03/20/198641.html</guid><wfw:comment>http://www.cppblog.com/chenjt3533/comments/198641.html</wfw:comment><comments>http://www.cppblog.com/chenjt3533/archive/2013/03/20/198641.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chenjt3533/comments/commentRss/198641.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenjt3533/services/trackbacks/198641.html</trackback:ping><description><![CDATA[<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"></div><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 16px; line-height: 26.66666603088379px; background-color: #ffffff;">一：BF算法<br /><span style="line-height: 26.66666603088379px;">&nbsp; &nbsp; &nbsp;如果让你写字符串的模式匹配，你可能会很快的写出朴素的bf算法，至少问题是解决了，我想大家很清楚的知道它的时间复</span><span style="line-height: 26.66666603088379px;">杂度为O（MN），原因很简单，主串和模式串失配的时候，我们总是将模式串的第一位与主串的下一个字符进行比较，所以复杂</span><span style="line-height: 26.66666603088379px;">度高在主串每次失配的时候都要回溯，图我就省略了。</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 16px; line-height: 26.66666603088379px; background-color: #ffffff;">&nbsp;<span style="line-height: 26.66666603088379px;">二：KMP算法<br /></span><span style="line-height: 26.66666603088379px;">&nbsp; &nbsp;刚才我们也说了，主串每次都要回溯，从而提高了时间复杂度，那么能不能在&#8220;主串&#8221;和&#8220;模式串&#8221;失配的情况下，主串不回溯呢？</span><span style="line-height: 26.66666603088379px;">而是让&#8221;模式串&#8220;向右滑动一定的距离，对上号后继续进行下一轮的匹配，从而做到时间复杂度为O（M+N）呢？所以kmp算法就是</span><span style="line-height: 26.66666603088379px;">用来处理这件事情的。</span></p><br />代码：<br /><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#pragma&nbsp;once<br /><br />#include&nbsp;&lt;iostream&gt;<br /><br /><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;---&nbsp;朴素匹配算法&nbsp;---&nbsp;</span><span style="color: #008000; "><br /></span><br /><span style="color: #0000FF; ">int</span>&nbsp;NaiveMatch(<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;*&nbsp;txt,&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;*&nbsp;pat)&nbsp;&nbsp;<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;&nbsp;nTxtLength&nbsp;=&nbsp;strlen(txt);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;&nbsp;nPatLength&nbsp;=&nbsp;strlen(pat);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;&nbsp;nTxt&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;&nbsp;nPat&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;nCount&nbsp;=&nbsp;0;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;计数</span><span style="color: #008000; "><br /></span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(nTxt&nbsp;&lt;=&nbsp;nTxtLength&nbsp;-&nbsp;nPatLength&nbsp;&amp;&amp;&nbsp;nPat&nbsp;&lt;&nbsp;nPatLength)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++nCount;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(pat[nPat]&nbsp;==&nbsp;txt[nTxt+nPat])<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++nPat;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">else</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++nTxt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nPat&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;"NaiveMatch,&nbsp;compare&nbsp;counts:&nbsp;"&nbsp;&lt;&lt;&nbsp;nCount&nbsp;&lt;&lt;&nbsp;std::endl;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;&nbsp;(nPat&nbsp;==&nbsp;nPatLength&nbsp;?&nbsp;nTxt&nbsp;:&nbsp;-1);<br />}&nbsp;<br /><br /><br /><br /><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;---&nbsp;KMP&nbsp;匹配算法&nbsp;---</span><span style="color: #008000; "><br /></span><br /><span style="color: #0000FF; ">void</span>&nbsp;GetNext(<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;pattern,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;next[])<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;next[0]&nbsp;=&nbsp;0;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;j&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;1;&nbsp;i&nbsp;&lt;&nbsp;strlen(pattern);&nbsp;i++)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>(&nbsp;j&nbsp;&gt;&nbsp;0&nbsp;&amp;&amp;&nbsp;pattern[j]&nbsp;!=&nbsp;pattern[i]&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j&nbsp;=&nbsp;next[j-1];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(pattern[j]&nbsp;==&nbsp;pattern[i])<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j++;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next[i]&nbsp;=&nbsp;j;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br /><span style="color: #0000FF; ">int</span>&nbsp;KMPMatch(<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;src,&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;pattern,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;next[])<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;nSrc&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;nPattern&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;nCount&nbsp;=&nbsp;0;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;计数</span><span style="color: #008000; "><br /></span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>(nSrc&nbsp;&lt;&nbsp;strlen(src)&nbsp;&amp;&amp;&nbsp;nPattern&nbsp;&lt;&nbsp;strlen(pattern))<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++nCount;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(0&nbsp;==&nbsp;nPattern&nbsp;||&nbsp;src[nSrc]&nbsp;==&nbsp;pattern[nPattern])<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++nPattern;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++nSrc;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">else</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nPattern&nbsp;=&nbsp;next[nPattern];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;"KMP,&nbsp;compare&nbsp;counts:&nbsp;"&nbsp;&lt;&lt;&nbsp;nCount&nbsp;&lt;&lt;&nbsp;std::endl;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;(nPattern&nbsp;==&nbsp;strlen(pattern)&nbsp;?&nbsp;nSrc&nbsp;-&nbsp;nPattern&nbsp;:&nbsp;-1);<br />}<br /><br /><br /><br /><span style="color: #0000FF; ">#define</span>&nbsp;PRINT_RESLUT(v)&nbsp;{&nbsp;if(-1&nbsp;==&nbsp;(v))&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;"No&nbsp;Find!";&nbsp;else&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;"Position&nbsp;=&nbsp;"&nbsp;&lt;&lt;&nbsp;(v);&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;std::endl&nbsp;&lt;&lt;&nbsp;std::endl;&nbsp;}<br /><br /><span style="color: #0000FF; ">int</span>&nbsp;main()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;Src&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;"abc1aabc1aabc1aaababc1aababc1aabc1aaabc1aabc1aababc1aaabaabcbc1aa";<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;Pattern&nbsp;=&nbsp;"abaabc";<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;nPos&nbsp;=&nbsp;-1;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;保存匹配到的位置</span><span style="color: #008000; "><br /></span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080; ">///</span><span style="color: #008000; ">&nbsp;朴素匹配算法</span><span style="color: #808080; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;nPos&nbsp;=&nbsp;NaiveMatch(Src,&nbsp;Pattern);<br />&nbsp;&nbsp;&nbsp;&nbsp;PRINT_RESLUT(nPos);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080; ">///</span><span style="color: #008000; ">&nbsp;KMP匹配算法</span><span style="color: #808080; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;next[6]&nbsp;=&nbsp;{0};<br />&nbsp;&nbsp;&nbsp;&nbsp;GetNext(Pattern,&nbsp;next);<br />&nbsp;&nbsp;&nbsp;&nbsp;nPos&nbsp;=&nbsp;KMPMatch(Src,&nbsp;Pattern,&nbsp;next);<br />&nbsp;&nbsp;&nbsp;&nbsp;PRINT_RESLUT(nPos);<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;system("pause");<br />&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />}</div><br />运行结果：<br /><img src="http://www.cppblog.com/images/cppblog_com/chenjt3533/结果.jpg" width="377" height="149" alt="" /><br /><div><br />疑惑：为什么KMP的效率会更低？<br /><img src="file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\richole\temp_8064_6.jpg" alt="" /></div><img src ="http://www.cppblog.com/chenjt3533/aggbug/198641.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenjt3533/" target="_blank">chenjt3533</a> 2013-03-20 19:06 <a href="http://www.cppblog.com/chenjt3533/archive/2013/03/20/198641.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C语言 malloc 工作机制</title><link>http://www.cppblog.com/chenjt3533/archive/2013/03/19/198591.html</link><dc:creator>chenjt3533</dc:creator><author>chenjt3533</author><pubDate>Tue, 19 Mar 2013 09:08:00 GMT</pubDate><guid>http://www.cppblog.com/chenjt3533/archive/2013/03/19/198591.html</guid><wfw:comment>http://www.cppblog.com/chenjt3533/comments/198591.html</wfw:comment><comments>http://www.cppblog.com/chenjt3533/archive/2013/03/19/198591.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/chenjt3533/comments/commentRss/198591.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenjt3533/services/trackbacks/198591.html</trackback:ping><description><![CDATA[<div></div><div>void *malloc (size_t stSize);</div><div>该函数在内存的动态存储区中分配 stSize 连续空间，返回值是一个指向所分配的连续存储域的起始地址的指针。</div><div></div><div><br />void free(void *firstbyte);</div><div>如果给定一个由先前的 malloc 返回的指针，那么该函数会将分配的空间归还给进程的&#8220;空闲空间&#8221;。</div><div></div><div><br />malloc 工作机制:</div><div>malloc函数的实质体现在，它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时，它沿连接表寻找一个大到足以满足用户请求所需要的内存块。然后，将该内存块一分为二（一块的大小与用户请求的大小相等，另一块的大小就是剩下的字节）。接下来，将分配给用户的那块内存传给用户，并将剩下的那块（如果有的话）返回到连接表上。调用free函数时，它将用户释放的内存块连接到空闲链上。到最后，空闲链会被切成很多的小内存片段，如果这时用户申请一个大的内存片段，那么空闲链上可能没有可以满足用户要求的片段了。于是，malloc函数请求延时，并开始在空闲链上翻箱倒柜地检查各内存片段，对它们进行整理，将相邻的小空闲块合并成较大的内存块。</div><div><div><br />参考：http://www.cnblogs.com/xkfz007/articles/2729027.html</div></div><img src ="http://www.cppblog.com/chenjt3533/aggbug/198591.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenjt3533/" target="_blank">chenjt3533</a> 2013-03-19 17:08 <a href="http://www.cppblog.com/chenjt3533/archive/2013/03/19/198591.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>类模板 与 模板类</title><link>http://www.cppblog.com/chenjt3533/archive/2013/03/13/198387.html</link><dc:creator>chenjt3533</dc:creator><author>chenjt3533</author><pubDate>Wed, 13 Mar 2013 09:11:00 GMT</pubDate><guid>http://www.cppblog.com/chenjt3533/archive/2013/03/13/198387.html</guid><wfw:comment>http://www.cppblog.com/chenjt3533/comments/198387.html</wfw:comment><comments>http://www.cppblog.com/chenjt3533/archive/2013/03/13/198387.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chenjt3533/comments/commentRss/198387.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenjt3533/services/trackbacks/198387.html</trackback:ping><description><![CDATA[<div></div><div>类模板：类是对象的抽象，而类模板又是类的抽象，可以用模板定义出具体类(模板类)。</div><div>模板类：就是用模板定义出的具体类。</div><div></div><div>我们知道c++的多态有两种，一是运行时的多态，也就是虚函数产生多态；二就是编译时的多态，它就是由类模板产生的多态。<br /><br />例子：<br /><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#include&nbsp;&lt;iostream&gt;<br /><br /><span style="color: #808080; ">///</span><span style="color: #008000; ">&nbsp;一个类模板</span><span style="color: #808080; "><br /></span>template&nbsp;&lt;typename&nbsp;T&gt;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;typename&nbsp;也可以用&nbsp;class</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">class</span>&nbsp;Base<br />{<br /><span style="color: #0000FF; ">public</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;PrintTypeName()&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;打印出&nbsp;T&nbsp;的类型</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;typeid(T).name()&nbsp;&lt;&lt;&nbsp;std::endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />};<br /><br />typedef&nbsp;Base&lt;<span style="color: #0000FF; ">int</span>&gt;&nbsp;&nbsp;IntBase;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;一个模板类</span><span style="color: #008000; "><br /></span>typedef&nbsp;Base&lt;<span style="color: #0000FF; ">char</span>&gt;&nbsp;CharBase;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;另一个模板类</span><span style="color: #008000; "><br /></span><br /><span style="color: #0000FF; ">int</span>&nbsp;main()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;IntBase*&nbsp;pIntBase&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;IntBase;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(NULL&nbsp;!=&nbsp;pIntBase)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pIntBase-&gt;PrintTypeName();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;pIntBase;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pIntBase&nbsp;=&nbsp;NULL;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;CharBase*&nbsp;pCharBase&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;CharBase;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(NULL&nbsp;!=&nbsp;pCharBase)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pCharBase-&gt;PrintTypeName();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;pCharBase;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pCharBase&nbsp;=&nbsp;NULL;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;system("pause");<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />}</div></div><div></div><img src ="http://www.cppblog.com/chenjt3533/aggbug/198387.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenjt3533/" target="_blank">chenjt3533</a> 2013-03-13 17:11 <a href="http://www.cppblog.com/chenjt3533/archive/2013/03/13/198387.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>区分重载(overload)，覆盖(Override)和隐藏(hide)</title><link>http://www.cppblog.com/chenjt3533/archive/2013/03/08/198302.html</link><dc:creator>chenjt3533</dc:creator><author>chenjt3533</author><pubDate>Fri, 08 Mar 2013 09:29:00 GMT</pubDate><guid>http://www.cppblog.com/chenjt3533/archive/2013/03/08/198302.html</guid><wfw:comment>http://www.cppblog.com/chenjt3533/comments/198302.html</wfw:comment><comments>http://www.cppblog.com/chenjt3533/archive/2013/03/08/198302.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chenjt3533/comments/commentRss/198302.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenjt3533/services/trackbacks/198302.html</trackback:ping><description><![CDATA[转自&nbsp;<a href="http://blog.csdn.net/jixingzhong/article/details/1858943">http://blog.csdn.net/jixingzhong/article/details/1858943</a>&nbsp;<br /><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">重载overload，这个概念是大家熟知的。在同一可访问区内被声名的几个具有不同参数列的（参数的类型、个数、顺序不同）同名函数，程序会根据不同的参数列来确定具体调用哪个函数，这种机制就是重载。重载不关心函数的返回值类型，即返回类型不同无法构成重载。此外，C++ 中的const成员函数也可以构成overload。<br />&nbsp;&nbsp;&nbsp; 总结一下重载的特征：<br />　　1、处在相同的空间中，即相同的范围内；<br />　　2、函数名相同；<br />　　3、参数不同，即参数个数不同，或相同位置的参数类型不同；<br />　　4、const成员函数可以和非const成员函数形成重载；<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5、virtual关键字、返回类型对是否够成重载无任何影响。</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "><br />&nbsp;&nbsp;&nbsp; 覆盖override，是指派生类中存在重新定义的函数，其函数名、参数列、返回值类型必须同父类中的相对应被覆盖的函数严格一致，覆盖函数和被覆盖函数只有函数体（花括号中的部分）不同，当派生类对象调用子类中该同名函数时会自动调用子类中的覆盖版本，而不是父类中的被覆盖函数版本，这种机制就叫做覆盖，特征是：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、不同的范围（分别位于派生类与基类）；&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、函数名字相同；&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3、参数相同；&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;4、基类函数必须有virtual关键字。&nbsp;&nbsp;</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">&nbsp;</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">针对上述两个概念，还有一个隐藏hide。所谓的隐藏，指的是派生类类型的对象、指针、引用访问基类和派生类都有的同名函数时，访问的是派生类的函数，即隐藏了基类的同名函数。隐藏规则的底层原因其实是Ｃ＋＋的名字解析过程。在继承机制下，派生类的类域被嵌套在基类的类域中。派生类的名字解析过程如下：<br />　　1、首先在派生类类域中查找该名字。<br />　　2、如果第一步中没有成功查找到该名字，即在派生类的类域中无法对该名字进行解析，则编译器在外围基类类域对查找该名字的定义。<br />&nbsp;&nbsp;&nbsp; 总结一下隐藏的特征：<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、如果派生类的函数与基类的函数同名，但是参数不同。此时，不论有无virtual关键字，基类的函数将被隐藏（注意别与重载混淆）。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、如果派生类的函数与基类的函数同名，并且参数也相同，但是基类函数没有virtual关键字。此时，基类的函数被隐藏（注意别与覆盖混淆）。&nbsp;</p><img src ="http://www.cppblog.com/chenjt3533/aggbug/198302.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenjt3533/" target="_blank">chenjt3533</a> 2013-03-08 17:29 <a href="http://www.cppblog.com/chenjt3533/archive/2013/03/08/198302.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c++ 函数重载</title><link>http://www.cppblog.com/chenjt3533/archive/2013/03/07/198257.html</link><dc:creator>chenjt3533</dc:creator><author>chenjt3533</author><pubDate>Thu, 07 Mar 2013 03:13:00 GMT</pubDate><guid>http://www.cppblog.com/chenjt3533/archive/2013/03/07/198257.html</guid><wfw:comment>http://www.cppblog.com/chenjt3533/comments/198257.html</wfw:comment><comments>http://www.cppblog.com/chenjt3533/archive/2013/03/07/198257.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chenjt3533/comments/commentRss/198257.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenjt3533/services/trackbacks/198257.html</trackback:ping><description><![CDATA[<div id="cnblogs_post_body" style="word-break: normal !important; color: #333333; font-family: Georgia, 'Times New Roman', Times, sans-serif; font-size: 16px; line-height: 33.33333206176758px; background-color: #ffffff; "><h4>&#8212;&#8212;每个现象后面都隐藏一个本质，关键在于我们是否去挖掘</h4><h4><strong>写在前面：</strong></h4><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">函数重载的重要性不言而明，但是你知道C++中函数重载是如何实现的呢（虽然本文谈的是C++中函数重载的实现，但我想其它语言也是类似的）？这个可以分解为下面两个问题</p><ul style="list-style-position: initial; list-style-image: initial; margin: 10px 10px 10px 45px; padding: 0px; "><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">1、声明/定义重载函数时，是如何解决命名冲突的？（抛开函数重载不谈，using就是一种解决命名冲突的方法，解决命名冲突还有很多其它的方法，这里就不论述了）</li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">2、当我们调用一个重载的函数时，又是如何去解析的？（即怎么知道调用的是哪个函数呢）</li></ul><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">这两个问题是任何支持函数重载的语言都必须要解决的问题！带着这两个问题，我们开始本文的探讨。本文的主要内容如下：</p><ul style="list-style-position: initial; list-style-image: initial; margin: 10px 10px 10px 45px; padding: 0px; "><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">&nbsp;<strong>1、例子引入（现象）</strong><ul style="list-style: disc; margin: 10px 10px 10px 45px; padding: 0px; "><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">什么是函数重载（what）？</li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">为什么需要函数重载（why）？</li></ul></li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; "><strong>2、编译器如何解决命名冲突的?</strong><ul style="list-style: disc; margin: 10px 10px 10px 45px; padding: 0px; "><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">函数重载为什么不考虑返回值类型</li></ul></li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; "><strong>3、重载函数的调用匹配</strong><ul style="list-style: disc; margin: 10px 10px 10px 45px; padding: 0px; "><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">模凌两可的情况</li></ul></li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; "><strong>4、编译器是如何解析重载函数调用的？</strong><ul style="list-style: disc; margin: 10px 10px 10px 45px; padding: 0px; "><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">根据函数名确定候选函数集</li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">确定可用函数</li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">确定最佳匹配函数</li></ul></li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; "><h4><strong>5、总结</strong></h4></li></ul><h4><strong>1、例子引入（现象）</strong></h4><h4><strong>1.1、什么是函数重载（what）？</strong></h4><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">函数重载是指在<span style="line-height: 1.8; color: #0000ff; ">同一作用域内</span>，可以有一组具有<span style="line-height: 1.8; color: #0000ff; ">相同函数名</span>，<span style="line-height: 1.8; color: #0000ff; ">不同参数列表</span>的函数，这组函数被称为重载函数。重载函数通常用来命名一组功能相似的函数，这样做减少了函数名的数量，避免了名字空间的污染，对于程序的可读性有很大的好处。</p><blockquote style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/bq.gif); background-color: #ffffff; color: #666666; margin: 0px auto; padding: 0px 0px 0px 45px; font-size: 13px; width: 1021.4888305664063px; background-position: 0% 0%; background-repeat: no-repeat no-repeat; "><p align="right" style="line-height: 1.8; margin-top: 8px; margin-bottom: 8px; ">When two or more different declarations are specified for a single name in the same scope,&nbsp; that name is said to&nbsp;<em>overloaded</em>.&nbsp; By extension, two declarations in the same scope that declare the same name but with different types are called&nbsp;<em>overloaded declarations</em>. Only function declarations can be overloaded; object and type declarations cannot be overloaded. &#8212;&#8212;摘自《ANSI C++ Standard. P290》</p></blockquote><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">看下面的一个例子，来体会一下：实现一个打印函数，既可以打印int型、也可以打印字符串型。在C++中，我们可以这样做：</p><div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; "><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">iostream</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;<br /></span><span style="color: #0000FF; ">using</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">namespace</span><span style="color: #000000; ">&nbsp;std;&nbsp;&nbsp;<br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;print(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i)&nbsp;<br />{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">print&nbsp;a&nbsp;integer&nbsp;:</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">i</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;&nbsp;<br />}&nbsp;<br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;print(</span><span style="color: #0000FF; ">string</span><span style="color: #000000; ">&nbsp;str)&nbsp;<br />{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">print&nbsp;a&nbsp;string&nbsp;:</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">str</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;&nbsp;<br />}&nbsp;<br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;main()&nbsp;<br />{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />print(</span><span style="color: #000000; ">12</span><span style="color: #000000; ">);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />print(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">hello&nbsp;world!</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br /></span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&nbsp;<br />}</span></div></pre></div><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">通过上面代码的实现，可以根据具体的print()的参数去调用print(int)还是print(string)。上面print(12)会去调用print(int)，print("hello world")会去调用print(string)，如下面的结果：（先用g++ test.c编译，然后执行）</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; "><a href="http://images.cnblogs.com/cnblogs_com/skynet/WindowsLiveWriter/C_D0B5/C++%E5%87%BD%E6%95%B0%E9%87%8D%E8%BD%BD%E4%BE%8B%E5%AD%901_2.png" style="outline-style: none; text-decoration: none; color: #3d81ee; border-bottom-width: 1px; border-bottom-style: dashed; "><img title="C  函数重载例子1" alt="C  函数重载例子1" src="http://images.cnblogs.com/cnblogs_com/skynet/WindowsLiveWriter/C_D0B5/C++%E5%87%BD%E6%95%B0%E9%87%8D%E8%BD%BD%E4%BE%8B%E5%AD%901_thumb.png" width="230" border="0" height="54" style="border: 0px #dddddd; display: inline; " /></a></p><h4><strong>1.2、为什么需要函数重载（why）？</strong></h4><ul style="list-style-position: initial; list-style-image: initial; margin: 10px 10px 10px 45px; padding: 0px; "><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">试想如果没有函数重载机制，如在C中，你必须要这样去做：为这个print函数取不同的名字，如print_int、print_string。这里还只是两个的情况，如果是很多个的话，就需要<span style="color: #ff8040; ">为实现同一个功能的函数取很多个名字</span>，如加入打印long型、char*、各种类型的数组等等。这样做很不友好！</li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">类的构造函数跟类名相同，也就是说：构造函数都同名。如果没有函数重载机制，要想实例化不同的对象，那是相当的麻烦！</li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">操作符重载，本质上就是函数重载，它大大丰富了已有操作符的含义，方便使用，如+可用于连接字符串等！</li></ul><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">通过上面的介绍我们对函数重载，应该唤醒了我们对函数重载的大概记忆。下面我们就来分析，C++是如何实现函数重载机制的。</p><h4><strong>2、<strong>编译器如何解决命名冲突的?</strong></strong></h4><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">为了了解编译器是如何处理这些重载函数的，我们反编译下上面我们生成的执行文件，看下汇编代码（全文都是在Linux下面做的实验，Windows类似，你也可以参考《<a href="http://www.cnblogs.com/skynet/archive/2010/07/11/1775084.html" style="outline-style: none; text-decoration: none; color: #3d81ee; border-bottom-width: 1px; border-bottom-style: dashed; ">一道简单的题目引发的思考</a>》一文，那里既用到Linux下面的反汇编和Windows下面的反汇编，并注明了Linux和Windows汇编语言的区别）。我们执行命令<span style="line-height: 1.8; color: #0000ff; ">objdump -d a.out &gt;log.txt</span>反汇编并将结果重定向到log.txt文件中，然后分析log.txt文件。</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">发现函数<span style="line-height: 1.8; color: #0000ff; ">void</span>&nbsp;print(<span style="line-height: 1.8; color: #0000ff; ">int</span>&nbsp;i) 编译之后为：（注意它的函数签名变为&#8212;&#8212;<span style="line-height: 1.8; color: #ff0000; "><strong>_Z5printi</strong></span>）</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; "><a href="http://images.cnblogs.com/cnblogs_com/skynet/WindowsLiveWriter/C_D0B5/image_2.png" style="outline-style: none; text-decoration: none; color: #3d81ee; border-bottom-width: 1px; border-bottom-style: dashed; "><img title="image" alt="image" src="http://images.cnblogs.com/cnblogs_com/skynet/WindowsLiveWriter/C_D0B5/image_thumb.png" width="644" border="0" height="324" style="border: 0px #dddddd; display: inline; " /></a></p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">发现函数<span style="line-height: 1.8; color: #0000ff; ">void</span>&nbsp;print(string str) 编译之后为：（注意它的函数签名变为&#8212;&#8212;<span style="line-height: 1.8; color: #ff0000; "><strong>_Z5printSs</strong></span>）</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; "><a href="http://images.cnblogs.com/cnblogs_com/skynet/WindowsLiveWriter/C_D0B5/image_4.png" style="outline-style: none; text-decoration: none; color: #3d81ee; border-bottom-width: 1px; border-bottom-style: dashed; "><img title="image" alt="image" src="http://images.cnblogs.com/cnblogs_com/skynet/WindowsLiveWriter/C_D0B5/image_thumb_1.png" width="644" border="0" height="343" style="border: 0px #dddddd; display: inline; " /></a></p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">我们可以发现编译之后，<strong>重载函数的名字变了不再都是print</strong>！这样不存在命名冲突的问题了，但又有新的问题了&#8212;&#8212;变名机制是怎样的，即如何将一个重载函数的签名映射到一个新的标识？我的第一反应是：<strong>函数名</strong>+<strong>参数列表</strong>，因为函数重载取决于参数的类型、个数，而跟返回类型无关。但看下面的映射关系：</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">void print(<span style="line-height: 1.8; color: #0000ff; ">int</span>&nbsp;i)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.8; color: #ff0000; "><strong>_Z5printi&nbsp;<br /></strong></span>void print(string str)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.8; color: #ff0000; "><strong>_Z5printSs</strong></span></p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">进一步猜想，前面的Z5表示返回值类型，print函数名，i表示整型int，Ss表示字符串string，即映射为<strong>返回类型</strong>+<strong>函数名</strong>+<strong>参数列表</strong>。最后在main函数中就是通过<span style="line-height: 1.8; color: #ff0000; "><strong>_Z5printi</strong></span>、<span style="line-height: 1.8; color: #ff0000; "><strong>_Z5printSs</strong></span>来调用对应的函数的：</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">80489bc:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e8 73 ff ff ff&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call&nbsp;&nbsp; 8048934&nbsp;<strong>&lt;_Z5printi&gt;</strong>&nbsp;<br />&#8230;&#8230;&#8230;&#8230;&#8230;&nbsp;<br />80489f0:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e8 7a ff ff ff&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call&nbsp;&nbsp; 804896f&nbsp;<strong>&lt;_Z5printSs&gt;</strong></p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">我们再写几个重载函数来验证一下猜想，如:</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">void print(long l)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.8; color: #ff0000; "><strong>_Z5printl&nbsp;<br /></strong></span>void print(char str)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.8; color: #ff0000; "><strong>_Z5printc</strong></span>&nbsp;<br />可以发现大概是int-&gt;i，long-&gt;l，char-&gt;c，string-&gt;Ss&#8230;.基本上都是用首字母代表，现在我们来现在一个函数的返回值类型是否真的对函数变名有影响，如：</p><div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; "><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">iostream</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">using</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">namespace</span><span style="color: #000000; ">&nbsp;std;<br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;max(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;a,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;b)&nbsp;<br />{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /></span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;a</span><span style="color: #000000; ">&gt;=</span><span style="color: #000000; ">b</span><span style="color: #000000; ">?</span><span style="color: #000000; ">a:b;&nbsp;<br />}&nbsp;&nbsp;<br /></span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">&nbsp;max(</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">&nbsp;a,</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">&nbsp;b)&nbsp;<br />{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /></span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;a</span><span style="color: #000000; ">&gt;=</span><span style="color: #000000; ">b</span><span style="color: #000000; ">?</span><span style="color: #000000; ">a:b;&nbsp;<br />}&nbsp;<br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;main()&nbsp;<br />{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">max&nbsp;int&nbsp;is:&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">max(</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,</span><span style="color: #000000; ">3</span><span style="color: #000000; ">)</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">max&nbsp;double&nbsp;is:&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">max(</span><span style="color: #000000; ">1.2</span><span style="color: #000000; ">,</span><span style="color: #000000; ">1.3</span><span style="color: #000000; ">)</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />}</span></div></pre></div><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; "><span style="line-height: 1.8; color: #0000ff; ">int</span>&nbsp;max(<span style="line-height: 1.8; color: #0000ff; ">int</span>&nbsp;a,<span style="line-height: 1.8; color: #0000ff; ">int</span>&nbsp;b) 映射为<span style="line-height: 1.8; color: #ff0000; "><strong>_Z3maxii</strong></span>、<span style="line-height: 1.8; color: #0000ff; ">double</span>&nbsp;max(<span style="line-height: 1.8; color: #0000ff; ">double</span>&nbsp;a,<span style="line-height: 1.8; color: #0000ff; ">double</span>&nbsp;b) 映射为<span style="line-height: 1.8; color: #ff0000; "><strong>_Z3maxdd，</strong></span>这证实了我的猜想，Z后面的数字代码各种返回类型。更加详细的对应关系，如那个数字对应那个返回类型，哪个字符代表哪重参数类型，就不去具体研究了，因为这个东西跟编译器有关，上面的研究都是基于g++编译器，如果用的是vs编译器的话，对应关系跟这个肯定不一样。但是规则是一样的：&#8220;<strong>返回类型</strong>+<strong>函数名</strong>+<strong>参数列表</strong>&#8221;。</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">既然返回类型也考虑到映射机制中，这样不同的返回类型映射之后的函数名肯定不一样了，但为什么不将函数返回类型考虑到函数重载中呢？&#8212;&#8212;这是为了保持解析操作符或函数调用时，独立于上下文（不依赖于上下文），看下面的例子</p><div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; "><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">float</span><span style="color: #000000; ">&nbsp;sqrt(</span><span style="color: #0000FF; ">float</span><span style="color: #000000; ">);&nbsp;<br /></span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">&nbsp;sqrt(</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">);&nbsp;&nbsp;<br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;f(</span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">&nbsp;da,&nbsp;</span><span style="color: #0000FF; ">float</span><span style="color: #000000; ">&nbsp;fla)&nbsp;<br />{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /></span><span style="color: #0000FF; ">float</span><span style="color: #000000; ">&nbsp;fl</span><span style="color: #000000; ">=</span><span style="color: #000000; ">sqrt(da);</span><span style="color: #008000; ">//</span><span style="color: #008000; ">调用sqrt(double)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">double</span><span style="color: #000000; ">&nbsp;d</span><span style="color: #000000; ">=</span><span style="color: #000000; ">sqrt(da);</span><span style="color: #008000; ">//</span><span style="color: #008000; ">调用sqrt(double)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">fl</span><span style="color: #000000; ">=</span><span style="color: #000000; ">sqrt(fla);</span><span style="color: #008000; ">//</span><span style="color: #008000; ">调用sqrt(float)</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">d</span><span style="color: #000000; ">=</span><span style="color: #000000; ">sqrt(fla);</span><span style="color: #008000; ">//</span><span style="color: #008000; ">调用sqrt(float)&nbsp;</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">}</span></div></pre></div><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">如果返回类型考虑到函数重载中，这样将不可能再独立于上下文决定调用哪个函数。</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">至此似乎已经完全分析清楚了，但我们还漏了函数重载的重要限定&#8212;&#8212;<strong>作用域</strong>。上面我们介绍的函数重载都是全局函数，下面我们来看一下一个类中的函数重载，用类的对象调用print函数，并根据实参调用不同的函数：</p><div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; "><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">#include</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">iostream</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;<br /></span><span style="color: #0000FF; ">using</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">namespace</span><span style="color: #000000; ">&nbsp;std;&nbsp;&nbsp;<br /></span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;test<br />{&nbsp;<br /></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;print(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">int</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;print(</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;c)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">char</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />}&nbsp;<br />};&nbsp;<br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;main()&nbsp;<br />{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />test&nbsp;t;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />t.print(</span><span style="color: #000000; ">1</span><span style="color: #000000; ">);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />t.print(</span><span style="color: #000000; ">'</span><span style="color: #000000; ">a</span><span style="color: #000000; ">'</span><span style="color: #000000; ">);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /></span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />&nbsp;}</span></div></pre></div><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">我们现在再来看一下这时print函数映射之后的函数名：</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; "><span style="line-height: 1.8; color: #0000ff; ">void</span>&nbsp;print(<span style="line-height: 1.8; color: #0000ff; ">int</span>&nbsp;i)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _<span style="line-height: 1.8; color: #ff0000; "><strong>ZN4test5printEi</strong></span></p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; "><span style="line-height: 1.8; color: #0000ff; ">void</span>&nbsp;print(<span style="line-height: 1.8; color: #0000ff; ">char</span>&nbsp;c)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _<span style="line-height: 1.8; color: #ff0000; "><strong>ZN4test5printEc</strong></span></p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">注意前面的N4test，我们可以很容易猜到应该表示作用域，N4可能为命名空间、test类名等等。这说明最准确的映射机制为：<strong>作用域</strong>+<strong>返回类型</strong>+<strong>函数名</strong>+<strong>参数列表</strong></p><h4><strong>3、重载函数的调用匹配</strong></h4><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">现在已经解决了重载函数命名冲突的问题，在定义完重载函数之后，用函数名调用的时候是如何去解析的？为了估计哪个重载函数最适合，需要依次按照下列规则来判断：</p><ul style="list-style-position: initial; list-style-image: initial; margin: 10px 10px 10px 45px; padding: 0px; "><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; "><strong>精确匹配</strong>：参数匹配而不做转换，或者只是做微不足道的转换，如数组名到指针、函数名到指向函数的指针、T到const T；</li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; "><strong>提升匹配</strong>：即整数提升（如bool 到 int、char到int、short 到int），float到double</li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; "><strong>使用标准转换匹配</strong>：如int 到double、double到int、double到long double、Derived*到Base*、T*到void*、int到unsigned int；</li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; "><strong>使用用户自定义匹配</strong>；</li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; "><strong>使用省略号匹配</strong>：类似printf中省略号参数</li></ul><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">如果在最高层有多个匹配函数找到，调用将被拒绝（因为有歧义、模凌两可）。看下面的例子：</p><div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; "><br /></pre></div><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">定义太少或太多的重载函数，都有可能导致模凌两可，看下面的一个例子：</p><div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; "><span style="color: #0000ff; ">void</span> f1(<span style="color: #0000ff; ">char</span>); <span style="color: #0000ff; ">void</span> f1(<span style="color: #0000ff; ">long</span>);  <span style="color: #0000ff; ">void</span> f2(<span style="color: #0000ff; ">char</span>*); <span style="color: #0000ff; ">void</span> f2(<span style="color: #0000ff; ">int</span>*);  <span style="color: #0000ff; ">void</span> k(<span style="color: #0000ff; ">int</span> i) {        f1(i);<span style="color: #008000; ">//调用f1(char)？ f1(long)？</span>        f2(0);<span style="color: #008000; ">//调用f2(char*)？f2(int*)？</span> }</pre></div><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">这时侯编译器就会报错，将错误抛给用户自己来处理：通过显示类型转换来调用等等（如f2(static_cast&lt;int *&gt;(0)，当然这样做很丑，而且你想调用别的方法时有用做转换）。上面的例子只是一个参数的情况，下面我们再来看一个两个参数的情况：</p><div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; "><span style="color: #0000ff; ">int</span> <span style="color: #0000ff; ">pow</span>(<span style="color: #0000ff; ">int</span> ,<span style="color: #0000ff; ">int</span>); <span style="color: #0000ff; ">double</span> <span style="color: #0000ff; ">pow</span>(<span style="color: #0000ff; ">double</span>,<span style="color: #0000ff; ">double</span>);  <span style="color: #0000ff; ">void</span> g() {        <span style="color: #0000ff; ">double</span> d=<span style="color: #0000ff; ">pow</span>(2.0,2)<span style="color: #008000; ">//调用pow(int(2.0),2)? pow(2.0,double(2))?</span> }</pre></div><h4><strong>4、编译器是如何解析重载函数调用的？</strong></h4><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">编译器实现调用重载函数解析机制的时候，肯定是首先找出同名的一些候选函数，然后从候选函数中找出最符合的，如果找不到就报错。下面介绍一种重载函数解析的方法：编译器在对重载函数调用进行处理时，由语法分析、C++文法、符号表、抽象语法树交互处理，交互图大致如下：</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; "><a href="http://images.cnblogs.com/cnblogs_com/skynet/WindowsLiveWriter/C_D0B5/image_8.png" style="outline-style: none; text-decoration: none; color: #3d81ee; border-bottom-width: 1px; border-bottom-style: dashed; "><img title="image" alt="image" src="http://images.cnblogs.com/cnblogs_com/skynet/WindowsLiveWriter/C_D0B5/image_thumb_3.png" width="463" border="0" height="364" style="border: 0px #dddddd; display: block; float: none; margin-left: auto; margin-right: auto; " /></a>&nbsp;</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">这个四个解析步骤所做的事情大致如下：</p><ul style="list-style-position: initial; list-style-image: initial; margin: 10px 10px 10px 45px; padding: 0px; "><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">由匹配文法中的函数调用，获取函数名；</li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">获得函数各参数表达式类型；</li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">语法分析器查找重载函数，符号表内部经过<strong>重载解析</strong>返回最佳的函数</li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">语法分析器创建抽象语法树，将符号表中存储的最佳函数绑定到抽象语法树上</li></ul><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">&nbsp;</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">下面我们重点解释一下重载解析，重载解析要满足前面《3、重载函数的调用匹配》中介绍的匹配顺序和规则。重载函数解析大致可以分为三步：</p><ul style="list-style-position: initial; list-style-image: initial; margin: 10px 10px 10px 45px; padding: 0px; "><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">根据函数名确定候选函数集</li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">从候选函数集中选择可用函数集合</li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">从可用函数集中确定最佳函数，或由于模凌两可返回错误</li></ul><h4><strong>4.1、</strong><strong>根据函数名确定候选函数集</strong></h4><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">根据函数在<strong>同一作用域内</strong>所有同名的函数，并且要求是可见的（像private、protected、public、friend之类）。&#8220;同一作用域&#8221;也是在函数重载的定义中的一个限定，如果不在一个作用域，不能算是函数重载，如下面的代码：</p><div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; "><span style="color: #0000ff; ">void</span> f(<span style="color: #0000ff; ">int</span>);  <span style="color: #0000ff; ">void</span> g() {         <span style="color: #0000ff; ">void</span> f(<span style="color: #0000ff; ">double</span>);         f(1); <span style="color: #008000; ">//这里调用的是f(double)，而不是f(int)</span> }</pre></div><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">即<strong>内层作用域的函数会隐藏外层的同名函数</strong>！<strong>同样的派生类的成员函数会隐藏基类的同名函数</strong>。这很好理解，变量的访问也是如此，如一个函数体内要访问全局的同名变量要用&#8220;::&#8221;限定。</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">为了查找候选函数集，一般采用<strong>深度优选</strong>搜索算法：</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">step1：从函数调用点开始查找，逐层作用域向外查找可见的候选函数&nbsp;<br />step2：如果上一步收集的不在用户自定义命名空间中，则用到了using机制引入的命名空间中的候选函数，否则结束</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">在收集候选函数时，如果调用函数的实参类型为非结构体类型，候选函数仅包含调用点可见的函数；如果调用函数的实参类型包括类类型对象、类类型指针、类类型引用或指向类成员的指针，候选函数为下面集合的并：</p><ul style="list-style-position: initial; list-style-image: initial; margin: 10px 10px 10px 45px; padding: 0px; "><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">(1)在调用点上可见的函数;</li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">(2)在定义该类类型的名字空间或定义该类的基类的名字空间中声明的函数;</li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">(3)该类或其基类的友元函数;</li></ul><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">下面我们来看一个例子更直观：</p><div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; "><span style="color: #0000ff; ">void</span> f(); <span style="color: #0000ff; ">void</span> f(<span style="color: #0000ff; ">int</span>); <span style="color: #0000ff; ">void</span> f(<span style="color: #0000ff; ">double</span>, <span style="color: #0000ff; ">double</span> = 314); names pace N {      <span style="color: #0000ff; ">void</span> f(<span style="color: #0000ff; ">char</span>3 ,<span style="color: #0000ff; ">char</span>3); } classA{     public: operat or <span style="color: #0000ff; ">double</span>() { } }; <span style="color: #0000ff; ">int</span> main ( ) {     using names pace N; <span style="color: #008000; ">//using指示符</span>     A a;     f(a);     <span style="color: #0000ff; ">return</span> 0; }</pre></div><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">&nbsp;</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">根据上述方法，由于实参是类类型的对象，候选函数的收集分为3步：</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">(1)从函数调用所在的main函数作用域内开始查找函数f的声明， 结果未找到。到main函数&nbsp;<br />作用域的外层作用域查找，此时在全局作用域找到3个函数f的声明，将它们放入候选集合；</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">(2)到using指示符所指向的命名空间 N中收集f ( char3 , char3 ) ；</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">(3)考虑2类集合。其一为定义该类类型的名字空间或定义该类的基类的名字空间中声明的函&nbsp;<br />数；其二为该类或其基类的友元函数。本例中这2类集合为空。</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">最终候选集合为上述所列的 4个函数f。</p><h4><strong>4.2、确定可用函数</strong></h4><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">可用的函数是指：函数参数个数匹配并且每一个参数都有隐式转换序列。</p><ul style="list-style-position: initial; list-style-image: initial; margin: 10px 10px 10px 45px; padding: 0px; "><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">(1)如果实参有m个参数，所有候选参数中，有且只有 m个参数；</li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">(2)所有候选参数中，参数个数不足m个，当前仅当参数列表中有省略号；</li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">(3)所有候选参数中，参数个数超过 m个，当前仅当第m + 1个参数以后都有缺省值。如果可用&nbsp;<br />集合为空，函数调用会失败。</li></ul><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">这些规则在前面的《3、重载函数的调用匹配》中就有所体现了。</p><h4><strong>4.3、确定最佳匹配函数</strong></h4><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">确定可用函数之后，对可用函数集中的每一个函数，如果调用函数的实参要调用它计算优先级，最后选出优先级最高的。如对《3、重载函数的调用匹配》中介绍的匹配规则中按顺序分配权重，然后计算总的优先级，最后选出最优的函数。</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">&nbsp;</p><h4><strong>5、总结</strong></h4><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">本文介绍了什么是函数重载、为什么需要函数重载、编译器如何解决函数重名问题、编译器如何解析重载函数的调用。通过本文，我想大家对C++中的重载应该算是比较清楚了。说明：在介绍函数名映射机制是基于g++编译器，不同的编译器映射有些差别；编译器解析重载函数的调用，也只是所有编译器中的一种。如果你对某个编译器感兴趣，请自己深入去研究。</p><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">最后我抛给大家两个问题：</p><ul style="list-style-position: initial; list-style-image: initial; margin: 10px 10px 10px 45px; padding: 0px; "><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">1、在C++中加号+，即可用于两个int型之间的相加、也可以用于浮点数数之间的相加、字符串之间的连接，那+算不算是操作符重载呢？换个场景C语言中加号+，即可用于两个int型之间的相加、也可以用于浮点数数之间的相加，那算不算操作符重载呢？</li><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">2、模板（template）的重载时怎么样的？模板函数和普通函数构成的重载，调用时又是如何匹配的呢？</li></ul><h4><strong>附录：一种C++函数重载机制</strong></h4><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">这个机制是由张素琴等人提出并实现的，他们写了一个C++的编译系统COC++（开发在国产机上，UNIX操作系统环境下具有中国自己版权的C、C++和FORTRAN语言编译系统，这些编译系统分别满足了ISOC90、AT&amp;T的C++85和ISOFORTRAN90标准）。COC++中的函数重载处理过程主要包括两个子过程：</p><ul style="list-style-position: initial; list-style-image: initial; margin: 10px 10px 10px 45px; padding: 0px; "><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">1、在函数声明时的处理过程中，编译系统建立函数声明原型链表，按照换名规则进行换名并在函数声明原型链表中记录函数换名后的名字（换名规则跟本文上面描述的差不多，只是那个int-》为哪个字符、char-》为哪个字符等等类似的差异）</li></ul><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; "><a href="http://images.cnblogs.com/cnblogs_com/skynet/WindowsLiveWriter/C_D0B5/image_6.png" style="outline-style: none; text-decoration: none; color: #3d81ee; border-bottom-width: 1px; border-bottom-style: dashed; "><img title="image" alt="image" src="http://images.cnblogs.com/cnblogs_com/skynet/WindowsLiveWriter/C_D0B5/image_thumb_2.png" width="361" border="0" height="528" style="border: 0px; display: block; float: none; margin-left: auto; margin-right: auto; " /></a></p><p align="center" style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">图附1、过程1-建立函数链表（说明，函数名的编码格式为：&lt;原函数名&gt;_&lt;作用域换名&gt;&lt;函数参数表编码&gt;，这跟g++中的有点不一样）</p><ul style="list-style-position: initial; list-style-image: initial; margin: 10px 10px 10px 45px; padding: 0px; "><li style="background-image: url(http://common.cnblogs.com/Skins/Minyx2_Lite/images/icon_miniarrow.gif); padding: 0px 0px 0px 15px; list-style: inherit; background-position: 0px 9px; background-repeat: no-repeat no-repeat; ">2、在函数调用语句翻译过程中，访问符号表，查找相应函数声明原型链表，按照类型匹配原则，查找最优匹配函数节点，并输出换名后的名字下面给出两个子过程的算法建立函数声明原型链表算法流程如图附1，函数调用语句翻译算法流程如图附2。</li></ul><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; "><a href="http://images.cnblogs.com/cnblogs_com/skynet/WindowsLiveWriter/C_D0B5/image_10.png" style="outline-style: none; text-decoration: none; color: #3d81ee; border-bottom-width: 1px; border-bottom-style: dashed; "><img title="image" alt="image" src="http://images.cnblogs.com/cnblogs_com/skynet/WindowsLiveWriter/C_D0B5/image_thumb_4.png" width="542" border="0" height="626" style="border: 0px; display: block; float: none; margin-left: auto; margin-right: auto; " /></a></p><p align="center" style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">图附2、过程2- 重载函数调用，查找链表</p><p align="center" style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">附-模板函数和普通函数构成的重载，调用时又是如何匹配的呢？</p><p align="center" style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">下面是C++创始人Bjarne Stroustrup的回答：</p><p align="center" style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">1)Find the set of function template specializations that will take part in overload resolution.</p><p align="center" style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">2)if two template functions can be called and one is more specified than the other, consider only the most specialized template function in the following steps.</p><p align="center" style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">3)Do overload resolution for this set of functions, plus any ordinary functions as for ordinary functions.</p><p align="center" style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">4)If a function and a specialization are equally good matches, the function is perferred.</p><p align="center" style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">5)If no match is found, the call is an error.</p><p align="center" style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">&nbsp;</p></div><div id="MySignature" style="margin-top: 10px; color: #333333; font-family: Georgia, 'Times New Roman', Times, sans-serif; font-size: 16px; line-height: 33.33333206176758px; background-color: #ffffff; "><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; "><br /></p><div id="SkynetSignature"><div><a href="http://www.cnblogs.com/skynet/" target="_blank" style="outline-style: none; text-decoration: none; color: #3d81ee; "></a></div><p style="line-height: 1.8; margin-top: 12px; margin-bottom: 12px; ">作者：吴秦<br />出处：http://www.cnblogs.com/skynet/</p></div></div><img src ="http://www.cppblog.com/chenjt3533/aggbug/198257.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenjt3533/" target="_blank">chenjt3533</a> 2013-03-07 11:13 <a href="http://www.cppblog.com/chenjt3533/archive/2013/03/07/198257.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++操作符重载</title><link>http://www.cppblog.com/chenjt3533/archive/2013/03/07/198256.html</link><dc:creator>chenjt3533</dc:creator><author>chenjt3533</author><pubDate>Thu, 07 Mar 2013 03:07:00 GMT</pubDate><guid>http://www.cppblog.com/chenjt3533/archive/2013/03/07/198256.html</guid><wfw:comment>http://www.cppblog.com/chenjt3533/comments/198256.html</wfw:comment><comments>http://www.cppblog.com/chenjt3533/archive/2013/03/07/198256.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chenjt3533/comments/commentRss/198256.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenjt3533/services/trackbacks/198256.html</trackback:ping><description><![CDATA[<div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; ">//原文链接：&nbsp;<a href="http://blog.csdn.net/xiegenwendada/article/details/8477209">http://blog.csdn.net/xiegenwendada/article/details/8477209</a>&nbsp;<br /><br />#include&lt;stdio.h&gt;&nbsp;&nbsp;<br />#include&nbsp;&lt;stdlib.h&gt;&nbsp;&nbsp;<br /><br /><span style="color: #008000; ">/*</span><span style="color: #008000; ">/////////////////////////////&nbsp;操作符重载&nbsp;////////////////////////////////////////////<br />-<br />-&nbsp;&nbsp;&nbsp;&nbsp;操作符重载必须是，参数类型或个数不同，还有是否为const，但不以返回值的类型左判断。<br />-<br />-&nbsp;&nbsp;&nbsp;&nbsp;------------------------------------------------------------------------------------&nbsp;&nbsp;&nbsp;&nbsp;<br />-&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;不能重载的操作符号&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;可以重载的操作符&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />-&nbsp;&nbsp;&nbsp;&nbsp;------------------------------------------------------------------------------------<br />-&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;.&nbsp;.*&nbsp;::&nbsp;?:&nbsp;new&nbsp;delete&nbsp;sizeof&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;new[]&nbsp;delete&nbsp;delete[]&nbsp;+&nbsp;-&nbsp;*&nbsp;/&nbsp;%&nbsp;^&nbsp;&nbsp;&nbsp;&nbsp;|<br />-&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;typeid&nbsp;static_cast&nbsp;dynamic_cast&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&amp;&nbsp;|&nbsp;~&nbsp;!&nbsp;=&nbsp;&lt;&nbsp;&gt;&nbsp;+=&nbsp;-=&nbsp;*=&nbsp;/=&nbsp;%=&nbsp;&nbsp;^=&nbsp;&amp;=&nbsp;|=&nbsp;&nbsp;&nbsp;&nbsp;|<br />-&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;const_cast&nbsp;reintERPret_cast&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&lt;&lt;&nbsp;&gt;&gt;&nbsp;&gt;&gt;=&nbsp;&lt;&lt;=&nbsp;==&nbsp;!=&nbsp;&lt;=&nbsp;&gt;=&nbsp;&amp;&amp;&nbsp;||&nbsp;++&nbsp;--&nbsp;&nbsp;&nbsp;&nbsp;|<br />-&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;-&gt;*&nbsp;-&gt;&nbsp;()&nbsp;[]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />-&nbsp;&nbsp;&nbsp;&nbsp;-------------------------------------------------------------------------------------<br />-&nbsp;&nbsp;&nbsp;&nbsp;<br />-<br />-&nbsp;&nbsp;&nbsp;&nbsp;------------------------------------------------------------------------------------&nbsp;&nbsp;&nbsp;&nbsp;<br />-&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;类成员操作符重载&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;友员函数操作符重载&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />-&nbsp;&nbsp;&nbsp;&nbsp;------------------------------------------------------------------------------------<br />-&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;左右操作数都是该类对象&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;左操作数为其它类型&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />-&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;必须为类成员操作符：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />-&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;赋值（=）,下标（[]）,调用（()）&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />-&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;和成员访问箭头（-&gt;）&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />-&nbsp;&nbsp;&nbsp;&nbsp;-------------------------------------------------------------------------------------<br />-<br />////////////////////////////////&nbsp;操作符重载&nbsp;////////////////////////////////////////////</span><span style="color: #008000; ">*/</span><br /><br /><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;简单的重载</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">class</span>&nbsp;CBaseOperator&nbsp;&nbsp;<br />{&nbsp;&nbsp;<br /><br /><span style="color: #0000FF; ">public</span>:&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;nData;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">测试的变量&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span><br /><span style="color: #0000FF; ">public</span>:&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;CBaseOperator(<span style="color: #0000FF; ">int</span>&nbsp;nData&nbsp;=&nbsp;0):nData(nData)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nData++;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--nData;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;CBaseOperator(<span style="color: #0000FF; ">const</span>&nbsp;CBaseOperator&amp;&nbsp;cBO)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nData&nbsp;=&nbsp;cBO.nData;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">重载=操作符，一般=操作符和拷贝构造函数是成对出现的。&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;CBaseOperator&amp;&nbsp;<span style="color: #0000FF; ">operator</span>=(<span style="color: #0000FF; ">const</span>&nbsp;CBaseOperator&amp;&nbsp;cBO)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nData&nbsp;=&nbsp;cBO.nData;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*<span style="color: #0000FF; ">this</span>;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /><br /><span style="color: #0000FF; ">public</span>:&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">重载+操作符,简单的二元操作符重载是最常见也是比较简单的。基本思路都是这样，注意如果&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">操作符出现在左边，则只能用友员了。这里了有几个返回类型是CBaseOperator，return&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">语句中却是两个int相加，这种情况是可以通过的，编译器会自动构建一个相应的对象返回，&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">前提是你的构造函数要有相应的参数，这里是int作为参数&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;<span style="color: #0000FF; ">operator</span>+(<span style="color: #0000FF; ">int</span>&nbsp;nAdd)&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;nData&nbsp;+&nbsp;nAdd;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;<span style="color: #0000FF; ">operator</span>+(<span style="color: #0000FF; ">int</span>&nbsp;nAdd)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;nData&nbsp;+&nbsp;nAdd;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;friend&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;<span style="color: #0000FF; ">operator</span>+(<span style="color: #0000FF; ">int</span>&nbsp;nAdd,<span style="color: #0000FF; ">const</span>&nbsp;CBaseOperator&amp;&nbsp;cAdd)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;nAdd&nbsp;+&nbsp;cAdd.nData;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;CBaseOperator&nbsp;<span style="color: #0000FF; ">operator</span>+(<span style="color: #0000FF; ">const</span>&nbsp;CBaseOperator&amp;&nbsp;cAdd)&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;nData&nbsp;+&nbsp;cAdd.nData;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">重载减法什么的也是一样。就不写了。哈哈&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">比较操作符重载==,!=,&gt;,&nbsp;&gt;=,&nbsp;&lt;,&nbsp;&lt;=总结：这里都是配套的操作一般来说如果写一个&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">都会重载其他几个，特别是==,!=。当然也有例外。哈哈。。&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;<span style="color: #0000FF; ">operator</span>==(<span style="color: #0000FF; ">const</span>&nbsp;CBaseOperator&amp;&nbsp;cEqual)&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;nData&nbsp;==&nbsp;cEqual.nData;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;<span style="color: #0000FF; ">operator</span>&nbsp;==&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;nEqual)&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;nData&nbsp;==&nbsp;nEqual;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;friend&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;<span style="color: #0000FF; ">operator</span>&nbsp;==(<span style="color: #0000FF; ">int</span>&nbsp;nEqual,&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;CBaseOperator&amp;&nbsp;cEqual)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;cEqual.nData&nbsp;==&nbsp;nEqual;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;<span style="color: #0000FF; ">operator</span>!=(<span style="color: #0000FF; ">const</span>&nbsp;CBaseOperator&amp;&nbsp;cEqual)&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;nData&nbsp;!=&nbsp;cEqual.nData;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">其他的也就不写了，基本一样。哈哈&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">重载++,--操作符,因为++,--有两种方式，一种是前增量(++XXX先改变自己，返回)，&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">一种是后增量（改变自己，返回改变前的状态)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">因为重载是判断参数的，为了能区别前增量和后增量，C++的设计者做了这样的考虑。&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">就是重载后增量的时候在参数列表中加一个int类型参数，这样就避免的重载的重复了。&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">在调用上，如果都重载，那么用int参数的是后增量++,没有参数的是前增量++，&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">(注：我在这里说的是成员函数，当然友员的重载参数个数要多一个，以后的我可别说我无知啊。)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">如果都重载，那么前增量和后增量都会调用相应的函数，如果只重载了后增量,那么前增量会失败&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">如果只重载了前增量，就会无论是前增量和后增量都会调用这个函数。所以一般他们也是成对&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">出现的，除非你懒，只写前增量，可惜如果人家要调用后增量呢？结果会错的哦。哈哈。&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">重载后增量.&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;CBaseOperator&nbsp;<span style="color: #0000FF; ">operator</span>++(<span style="color: #0000FF; ">int</span>)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CBaseOperator&nbsp;cTemp&nbsp;=&nbsp;*<span style="color: #0000FF; ">this</span>;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++nData;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;cTemp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">重载前增量&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;CBaseOperator&amp;&nbsp;<span style="color: #0000FF; ">operator</span>++()&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++nData;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*<span style="color: #0000FF; ">this</span>;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">重载--操作符是一样的，也不写了。&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">重载[],()等操作符号,同样[]的参数个数是确定的。&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">我之说以把他们写一起，是因为我错误的以为[]的参数个数是可以自己定义。错了错了。&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">知错能改是好的，对了，()的参数个数是可以自己定义的。这个就给我们很大的发挥空间了。&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">都忘了[],()&nbsp;=&nbsp;等操作符必须是成员函数，上面有写。不能用友员和静态成员函数&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">重载[]&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;<span style="color: #0000FF; ">operator</span>[](<span style="color: #0000FF; ">int</span>&nbsp;nIndex)&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;nIndex;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">重载()&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;<span style="color: #0000FF; ">operator</span>()(<span style="color: #0000FF; ">int</span>&nbsp;a)&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;a;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;<span style="color: #0000FF; ">operator</span>()(<span style="color: #0000FF; ">int</span>&nbsp;a,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;b)&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;a&nbsp;&gt;&nbsp;b;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;CBaseOperator&nbsp;<span style="color: #0000FF; ">operator</span>()(<span style="color: #0000FF; ">int</span>&nbsp;a,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;b,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;c)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;CBaseOperator(a+b+c+*<span style="color: #0000FF; ">this</span>);&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">重载*,-&gt;的操作符,*操作符就是相当于指针的*p;不过这里已经失去了原来的意义，他不是一个指针了。&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">但如果是想通过他来得到一些东西，也是可以的，特别在迭代器中常用这种方法。-&gt;也是和*配对出现的。&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">不过-&gt;操作符比较有意思，貌似和(*p).dddd真的差不多，所以返回的应该是一个结构的指针，我们这里&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">就返回了本身，当然可以返回任何结构的指针的。（并不是只能返回本身）。&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">重载*，这里参数个数是固定的，多写一个就成了乘法的操作了。哈哈&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;<span style="color: #0000FF; ">operator</span>*()&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;nData;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">重载-&gt;&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;CBaseOperator*&nbsp;<span style="color: #0000FF; ">operator</span>-&gt;()&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">this</span>;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">其他的例如&amp;&amp;&nbsp;||&nbsp;这样的操作符还是不重载的好。利用其原有的本性&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">重载new&nbsp;delete,这里编译器做了一个限制，new必须返回void*类型，&nbsp;delete必须&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">返回void类型。(上面说过函数重载是不检查返回类型的，和这里并没有冲突，他只是限定了返回&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">类型，而不是只有返回类型不同的函数能重载，这个是编译器做的工作，一定上确保new能更好的工作吧)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">还有就是他们的参数个数都是可以自定义的。new&nbsp;和&nbsp;new[]&nbsp;是两个不同的操作符，所以还是要分别重载一下。&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">delete&nbsp;和&nbsp;delete[]&nbsp;也是两个不同的操作符。这里只重载了一个。&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>*&nbsp;<span style="color: #0000FF; ">operator</span>&nbsp;<span style="color: #0000FF; ">new</span>(size_t&nbsp;size)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;&nbsp;malloc(size);&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>*&nbsp;<span style="color: #0000FF; ">operator</span>&nbsp;<span style="color: #0000FF; ">new</span>[](size_t&nbsp;size)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;&nbsp;malloc(size);&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;<span style="color: #0000FF; ">operator</span>&nbsp;delete(<span style="color: #0000FF; ">void</span>*&nbsp;P,&nbsp;unsigned&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;size)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size&nbsp;=&nbsp;0;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free(P);&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br />};&nbsp;&nbsp;<br /><br /><span style="color: #0000FF; ">int</span>&nbsp;test_OverLoad()&nbsp;&nbsp;<br />{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;CBaseOperator&nbsp;cCo1(100);&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">判断+重载符&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;nSum&nbsp;=&nbsp;cCo1&nbsp;+&nbsp;50;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",&nbsp;nSum);&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;nSum&nbsp;=&nbsp;50&nbsp;+&nbsp;cCo1;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",&nbsp;nSum);&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">这里顺便检测一下拷贝构造函数&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;CBaseOperator&nbsp;co2(20);&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;CBaseOperator&nbsp;co3&nbsp;=&nbsp;co2&nbsp;+&nbsp;cCo1;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;nSum&nbsp;=&nbsp;co3.nData;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",&nbsp;nSum);&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;nSum&nbsp;=&nbsp;co3&nbsp;+&nbsp;60;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",&nbsp;nSum);&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">检测+，和=操作符&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;co3&nbsp;=&nbsp;10&nbsp;+&nbsp;cCo1&nbsp;+&nbsp;co2&nbsp;+&nbsp;20;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;nSum&nbsp;=&nbsp;co3.nData;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",&nbsp;nSum);&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">查看比较操作符&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(cCo1&nbsp;==&nbsp;cCo1&nbsp;&amp;&amp;&nbsp;cCo1&nbsp;==&nbsp;100&nbsp;&amp;&amp;&nbsp;100&nbsp;==&nbsp;cCo1)&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("True\n");&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;co3&nbsp;=&nbsp;co2;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(!(co3&nbsp;!=&nbsp;co2))&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("True\n");&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">增量操作符，cCo1是不能做这个操作的，因为他是常量&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;nSum&nbsp;=&nbsp;co2.nData;&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",&nbsp;nSum);&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;nSum&nbsp;=&nbsp;(co2++).nData;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",&nbsp;nSum);&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;nSum&nbsp;=&nbsp;(++co2).nData;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",&nbsp;nSum);&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">测试[],&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;nSum&nbsp;=&nbsp;cCo1[45];&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",&nbsp;nSum);&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">测试()&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;nSum&nbsp;=&nbsp;cCo1(50);&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",&nbsp;nSum);&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(cCo1(45,&nbsp;23))&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("True\n");&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;co2&nbsp;=&nbsp;co3(10,20,30);&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;nSum&nbsp;=&nbsp;co2.nData;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",&nbsp;nSum);&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">测试*,这里co2并不是指针哦。只是重载了*的操作符&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;nSum&nbsp;=&nbsp;*co2;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",&nbsp;nSum);&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">测试-&gt;,这里也一样。&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;nSum&nbsp;=&nbsp;co2-&gt;nData;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",&nbsp;nSum);&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">测试new&nbsp;new[]&nbsp;delete,&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">这里没有测试输出。单步就知道了。&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;CBaseOperator*&nbsp;pCb1&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;CBaseOperator();&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;CBaseOperator*&nbsp;pCb2&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;CBaseOperator[10];&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;pCb1;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;pCb2;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;system("pause");&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;&nbsp;&nbsp;<br />}&nbsp;</div></div></div><img src ="http://www.cppblog.com/chenjt3533/aggbug/198256.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenjt3533/" target="_blank">chenjt3533</a> 2013-03-07 11:07 <a href="http://www.cppblog.com/chenjt3533/archive/2013/03/07/198256.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++四种强制转换</title><link>http://www.cppblog.com/chenjt3533/archive/2013/03/05/198235.html</link><dc:creator>chenjt3533</dc:creator><author>chenjt3533</author><pubDate>Tue, 05 Mar 2013 09:56:00 GMT</pubDate><guid>http://www.cppblog.com/chenjt3533/archive/2013/03/05/198235.html</guid><wfw:comment>http://www.cppblog.com/chenjt3533/comments/198235.html</wfw:comment><comments>http://www.cppblog.com/chenjt3533/archive/2013/03/05/198235.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chenjt3533/comments/commentRss/198235.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenjt3533/services/trackbacks/198235.html</trackback:ping><description><![CDATA[<p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">1&nbsp;static_cast&nbsp;&lt;&nbsp;type-id&nbsp;&gt;&nbsp;(&nbsp;expression&nbsp;)用法：</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">该运算符把expression转换为type-id类型，但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法：</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">&#9312;用于类层次结构中基类（父类）和派生类（子类）之间指针或引用的转换。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">进行上行转换（把派生类的指针或引用转换成基类表示）是安全的；</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">进行下行转换（把基类指针或引用转换成派生类表示）时，由于没有动态类型检查，所以是不安全的。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">&#9313;用于基本数据类型之间的转换，如把int转换成char，把int转换成enum。这种转换的安全性也要开发人员来保证。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">&#9314;把空指针转换成目标类型的空指针。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">&#9315;把任何类型的表达式转换成void类型。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">注意：static_cast不能转换掉expression的const、volatile、或者__unaligned属性。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">C++中static_cast和reinterpret_cast的区别</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">C++primer第五章里写了编译器隐式执行任何类型转换都可由static_cast显示完成;reinterpret_cast通常为操作数的位模式提供较低层的重新解释</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">1、C++中的static_cast执行非多态的转换，用于代替C中通常的转换操作。因此，被做为隐式类型转换使用。比如：</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i;<br /></span><span style="color: #0000FF; ">float</span><span style="color: #000000; ">&nbsp;f&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">166.7f</span><span style="color: #000000; ">;<br />i&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;static_cast</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">(f);</span></div></p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">此时结果，i的值为166。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">2、C++中的reinterpret_cast主要是将数据从一种类型的转换为另一种类型。所谓&#8220;通常为操作数的位模式提供较低层的重新解释&#8221;也就是说将数据以二进制存在形式的重新解释。比如：</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i;<br /></span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">p&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">This&nbsp;is&nbsp;a&nbsp;example.</span><span style="color: #000000; ">"</span><span style="color: #000000; ">;<br />i&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;reinterpret_cast</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">(p);</span></div></p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">此时结果，i与p的值是完全相同的。reinterpret_cast的作用是说将指针p的值以二进制（位模式）的方式被解释为整型，并赋给i，//i也是指针，整型指针；一个明显的现象是在转换前后没有数位损失。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "><br /></p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">2&nbsp;dynamic_cast&nbsp;&lt;&nbsp;type-id&nbsp;&gt;&nbsp;(&nbsp;expression&nbsp;)用法：</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">该运算符把expression转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void*；</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">如果type-id是类指针类型，那么expression也必须是一个指针，如果type-id是一个引用，那么expression也必须是一个引用。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">dynamic_cast运算符可以在执行期决定真正的类型。如果downcast是安全的（也就说，如果基类指针或者引用确实指向一个派生类对象）这个运算符会传回适当转型过的指针。如果downcast不安全，这个运算符会传回空指针（也就是说，基类指针或者引用没有指向一个派生类对象）。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">dynamic_cast主要用于类层次间的上行转换和下行转换，还可以用于类之间的交叉转换。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">在类层次间进行上行转换时，dynamic_cast和static_cast的效果是一样的；</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">在进行下行转换时，dynamic_cast具有类型检查的功能，比static_cast更安全。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;B<br />{<br /></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">:<br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;m_iNum;<br /></span><span style="color: #0000FF; ">virtual</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;foo();<br />};<br /><br /></span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;D:</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;B<br />{<br /></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">:<br /></span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">m_szName[</span><span style="color: #000000; ">100</span><span style="color: #000000; ">];<br />};<br /><br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;func(B&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">pb)<br />{<br />D&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">pd1&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;static_cast</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">D&nbsp;</span><span style="color: #000000; ">*&gt;</span><span style="color: #000000; ">(pb);<br />D&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">pd2&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;dynamic_cast</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">D&nbsp;</span><span style="color: #000000; ">*&gt;</span><span style="color: #000000; ">(pb);<br />}</span></div></p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">在上面的代码段中，如果pb指向一个D类型的对象，pd1和pd2是一样的，并且对这两个指针执行D类型的任何操作都是安全的；</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">但是，如果pb指向的是一个B类型的对象，那么pd1将是一个指向该对象的指针，对它进行D类型的操作将是不安全的（如访问m_szName），而pd2将是一个空指针。B要有虚函数，否则会编译出错；static_cast则没有这个限制。B中需要检测有虚函数的原因：类中存在虚函数，就说明它有想要让基类指针或引用指向派生类对象的情况，此时转换才有意义。这是由于运行时类型检查需要运行时类型信息，而这个信息存储在类的虚函数表（关于虚函数表的概念，详细可见&lt;Inside&nbsp;c++&nbsp;object&nbsp;model&gt;）中，只有定义了虚函数的类才有虚函数表，</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">3&nbsp;reinterpret_cast&lt;type-id&gt;&nbsp;(expression)用法：</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">该运算符的用法比较多。type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">它可以把一个指针转换成一个整数，也可以把一个整数转换成一个指针（先把一个指针转换成一个整数，</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">在把该整数转换成原类型的指针，还可以得到原先的指针值）。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "><br /></p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">4&nbsp;const_cast&lt;type_id&gt;&nbsp;(expression)用法：</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">该运算符用来修改类型的const或volatile属性。除了const&nbsp;或volatile修饰之外，&nbsp;type_id和expression的类型是一样的。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">常量指针被转化成非常量指针，并且仍然指向原来的对象；</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">常量引用被转换成非常量引用，并且仍然指向原来的对象；常量对象被转换成非常量对象。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">举如下一例：</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;B<br />{<br /></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">:<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;m_iNum;<br />}<br /><br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;foo()<br />{<br /></span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;B&nbsp;b1;<br />b1.m_iNum&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">100</span><span style="color: #000000; ">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">comile&nbsp;error</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">B&nbsp;b2&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;const_cast</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">B</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">(b1);<br />b2.&nbsp;m_iNum&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">200</span><span style="color: #000000; ">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">fine</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">}</span></div></p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">上面的代码编译时会报错，因为b1是一个常量对象，不能对它进行改变；</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">使用const_cast把它转换成一个常量对象，就可以对它的数据成员任意改变。注意：b1和b2是两个不同的对象。</p><img src ="http://www.cppblog.com/chenjt3533/aggbug/198235.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenjt3533/" target="_blank">chenjt3533</a> 2013-03-05 17:56 <a href="http://www.cppblog.com/chenjt3533/archive/2013/03/05/198235.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vc++ 网络编程</title><link>http://www.cppblog.com/chenjt3533/archive/2013/03/05/198226.html</link><dc:creator>chenjt3533</dc:creator><author>chenjt3533</author><pubDate>Tue, 05 Mar 2013 05:47:00 GMT</pubDate><guid>http://www.cppblog.com/chenjt3533/archive/2013/03/05/198226.html</guid><wfw:comment>http://www.cppblog.com/chenjt3533/comments/198226.html</wfw:comment><comments>http://www.cppblog.com/chenjt3533/archive/2013/03/05/198226.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chenjt3533/comments/commentRss/198226.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenjt3533/services/trackbacks/198226.html</trackback:ping><description><![CDATA[<p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">在网络编程中最常用的方案便是Client/Server (客户机/服务器)模型。在这种方案中客户应用程序向服务器程序请求服务。一个服务程序通常在一个众所周知的地址监听对服务的请求，也就是说，服务进程一直处于休眠状态，直到一个客户向这个服务的地址提出了连接请求。在这个时刻，服务程序被"惊醒"并且为客户提供服务－对客户的请求作出适当的反应。<br /><br />　　为了方便这种Client/Server模型的网络编程，90年代初，由Microsoft联合了其他几家公司共同制定了一套WINDOWS下的网络编程接口，即Windows Sockets规范，它不是一种网络协议,而是一套开放的、支持多种协议的Windows下的网络编程接口。现在的Winsock已经基本上实现了与协议无关，你可以使用Winsock来调用多种协议的功能，但较常使用的是TCP/IP协议。Socket实际在计算机中提供了一个通信端口，可以通过这个端口与任何一个具有Socket接口的计算机通信。应用程序在网络上传输，接收的信息都通过这个Socket接口来实现。<br /><br />　　微软为 Visual C++定义了Winsock类如CAsyncSocket类和派生于CAsyncSocket 的CSocket类，它们简单易用，读者朋友当然可以使用这些类来实现自己的网络程序，但是为了更好的了解Winsock API编程技术，我们这里探讨怎样使用底层的API函数实现简单的 Winsock 网络应用程式设计，分别说明如何在Server端和Client端操作Socket，实现基于TCP/IP的数据传送，最后给出相关的源代码。<br /><br />　　在VC中进行WINSOCK的API编程开发的时候，需要在项目中使用下面的三个文件，否则会出现编译错误。<br /><br />　　1．WINSOCK.H: 这是WINSOCK API的头文件，需要包含在项目中。<br /><br />　　2．WSOCK32.LIB: WINSOCK API连接库文件。在使用中，一定要把它作为项目的非缺省的连接库包含到项目文件中去。&nbsp;<br /><br />　　3．WINSOCK.DLL: WINSOCK的动态连接库，位于WINDOWS的安装目录下。<br /><br />　　<strong>服务器端操作 socket（套接字）</strong><br /><br />　　1．在初始化阶段调用WSAStartup()<br /><br />　　此函数在应用程序中初始化Windows Sockets DLL ，只有此函数调用成功后，应用程序才可以再调用其他Windows Sockets DLL中的API函数。在程式中调用该函数的形式如下：WSAStartup((WORD)((1&lt;&lt;8|1)，（LPWSADATA）&amp;WSAData)，其中(1&lt;&lt;8|1)表示我们用的是WinSocket1.1版本，WSAata用来存储系统传回的关于WinSocket的资料。<br /><br />　　2、建立Socket<br /><br />　　初始化WinSock的动态连接库后，需要在服务器端建立一个监听的Socket，为此可以调用Socket()函数用来建立这个监听的Socket，并定义此Socket所使用的通信协议。此函数调用成功返回Socket对象，失败则返回INVALID_SOCKET(调用WSAGetLastError()可得知原因，所有WinSocket 的API函数都可以使用这个函数来获取失败的原因)。<br /><br />　　SOCKET PASCAL FAR socket( int af, int type, int protocol )<br /><br />　　参数: af:目前只提供 PF_INET(AF_INET)；<br /><br />　　　　　type：Socket 的类型 (SOCK_STREAM、SOCK_DGRAM)；<br /><br />　　　　　protocol：通讯协定(如果使用者不指定则设为0)；<br /><br />　　如果要建立的是遵从TCP/IP协议的socket，第二个参数type应为SOCK_STREAM，如为UDP（数据报）的socket，应为SOCK_DGRAM。<br /><br />　　3、绑定端口<br /><br />　　接下来要为服务器端定义的这个监听的Socket指定一个地址及端口（Port），这样客户端才知道待会要连接哪一个地址的哪个端口，为此我们要调用bind()函数，该函数调用成功返回0，否则返回SOCKET_ERROR。<br /><br />　　int PASCAL FAR bind( SOCKET s, const struct sockaddr FAR *name,int namelen );<br /><br />　　参 数： s：Socket对象名；<br /><br />　　　　　　name：Socket的地址值，这个地址必须是执行这个程式所在机器的IP地址；<br /><br />　　　　　　namelen：name的长度；&nbsp;<br /><br />　　如果使用者不在意地址或端口的值，那么可以设定地址为INADDR_ANY，及Port为0，Windows Sockets 会自动将其设定适当之地址及Port (1024 到 5000之间的值)。此后可以调用getsockname()函数来获知其被设定的值。<br /><br />　　4、监听<br /><br />　　当服务器端的Socket对象绑定完成之后,服务器端必须建立一个监听的队列来接收客户端的连接请求。listen()函数使服务器端的Socket 进入监听状态，并设定可以建立的最大连接数(目前最大值限制为 5, 最小值为1)。该函数调用成功返回0，否则返回SOCKET_ERROR。<br /><br />　　int PASCAL FAR listen( SOCKET s, int backlog );<br /><br />　　参 数： s：需要建立监听的Socket；<br /><br />　　　　　　backlog：最大连接个数；<br /><br />　　服务器端的Socket调用完listen（）后，如果此时客户端调用connect（）函数提出连接申请的话，Server 端必须再调用accept() 函数，这样服务器端和客户端才算正式完成通信程序的连接动作。为了知道什么时候客户端提出连接要求，从而服务器端的Socket在恰当的时候调用 accept()函数完成连接的建立，我们就要使用WSAAsyncSelect（）函数，让系统主动来通知我们有客户端提出连接请求了。该函数调用成功返回0，否则返回SOCKET_ERROR。<br /><br />　　int PASCAL FAR WSAAsyncSelect( SOCKET s, HWND hWnd,unsigned int wMsg, long lEvent );<br /><br />　　参数： s：Socket 对象；<br />　<br />　　　　　hWnd ：接收消息的窗口句柄；<br /><br />　　　　　wMsg：传给窗口的消息；<br /><br />　　　　　lEvent：被注册的网络事件，也即是应用程序向窗口发送消息的网路事件，该值为下列值FD_READ、FD_WRITE、FD_OOB、 FD_ACCEPT、FD_CONNECT、FD_CLOSE的组合，各个值的具体含意为FD_READ：希望在套接字S收到数据时收到消息；FD_WRITE：希望在套接字S上可以发送数据时收到消息；FD_ACCEPT：希望在套接字S上收到连接请求时收到消息；FD_CONNECT：希望在套接字S上连接成功时收到消息；FD_CLOSE：希望在套接字S上连接关闭时收到消息；FD_OOB：希望在套接字S上收到带外数据时收到消息。具体应用时，wMsg应是在应用程序中定义的消息名称，而消息结构中的lParam则为以上各种网络事件名称。所以，可以在窗口处理自定义消息函数中使用以下结构来响应Socket的不同事件：　　<br /><br />switch(lParam)　<br />{<br />　case FD_READ:<br />　　 &#8230;　　<br />　　 break;<br />　case FD_WRITE:<br />　　 &#8230;<br />　　 break;<br />　&#8230;<br />}</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "><br />　　5、服务器端接受客户端的连接请求<br /><br />　　当Client提出连接请求时，Server 端hwnd视窗会收到Winsock Stack送来我们自定义的一个消息，这时，我们可以分析lParam，然后调用相关的函数来处理此事件。为了使服务器端接受客户端的连接请求，就要使用 accept() 函数，该函数新建一Socket与客户端的Socket相通，原先监听之Socket继续进入监听状态，等待他人的连接要求。该函数调用成功返回一个新产生的Socket对象，否则返回INVALID_SOCKET。<br /><br />　　SOCKET PASCAL FAR accept( SCOKET s, struct sockaddr FAR *addr,int FAR *addrlen );<br /><br />　　参数：s：Socket的识别码；<br /><br />　　　　　addr：存放来连接的客户端的地址；<br /><br />　　　　　addrlen：addr的长度<br /><br />　　6、结束 socket 连接<br /><br />　　结束服务器和客户端的通信连接是很简单的，这一过程可以由服务器或客户机的任一端启动，只要调用closesocket()就可以了，而要关闭 Server端监听状态的socket，同样也是利用此函数。另外，与程序启动时调用WSAStartup()憨数相对应，程式结束前，需要调用 WSACleanup() 来通知Winsock Dll释放Socket所占用的资源。这两个函数都是调用成功返回0，否则返回SOCKET_ERROR。<br /><br />　　int PASCAL FAR closesocket( SOCKET s );<br /><br />　　参数：s：Socket 的识别码；<br /><br />　　int PASCAL FAR WSACleanup( void );<br /><br />　　参数： 无</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "><strong>（二）实现例子</strong></p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">服务器端：</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdio.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Winsock2.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#pragma&nbsp;comment(lib,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">ws2_32.lib</span><span style="color: #000000; ">"</span><span style="color: #000000; ">)<br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;main()<br />{<br />WORD&nbsp;wVersionRequested;<br />WSADATA&nbsp;wsaData;<br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;err;<br /><br />wVersionRequested&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;MAKEWORD(&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">&nbsp;);<br /><br />err&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;WSAStartup(&nbsp;wVersionRequested,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">wsaData&nbsp;);<br /></span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(&nbsp;err&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">&nbsp;)&nbsp;{<br /></span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">;<br />}<br /><br /></span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(&nbsp;LOBYTE(&nbsp;wsaData.wVersion&nbsp;)&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">1</span><span style="color: #000000; ">||</span><span style="color: #000000; "><br />HIBYTE(&nbsp;wsaData.wVersion&nbsp;)&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">1</span><span style="color: #000000; ">&nbsp;)&nbsp;{<br />WSACleanup(&nbsp;);<br /></span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">;<br />}<br />SOCKET&nbsp;sockSrv</span><span style="color: #000000; ">=</span><span style="color: #000000; ">socket(AF_INET,SOCK_STREAM,</span><span style="color: #000000; ">0</span><span style="color: #000000; ">);<br /><br />SOCKADDR_IN&nbsp;addrSrv;<br />addrSrv.sin_addr.S_un.S_addr</span><span style="color: #000000; ">=</span><span style="color: #000000; ">htonl(INADDR_ANY);<br />addrSrv.sin_family</span><span style="color: #000000; ">=</span><span style="color: #000000; ">AF_INET;<br />addrSrv.sin_port</span><span style="color: #000000; ">=</span><span style="color: #000000; ">htons(</span><span style="color: #000000; ">6000</span><span style="color: #000000; ">);<br /><br />bind(sockSrv,(SOCKADDR</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">addrSrv,</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(SOCKADDR));</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;绑定端口</span><span style="color: #008000; "><br /></span><span style="color: #000000; "><br />listen(sockSrv,</span><span style="color: #000000; ">5</span><span style="color: #000000; ">);<br /><br />SOCKADDR_IN&nbsp;addrClient;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;连接上的客户端ip地址</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;len</span><span style="color: #000000; ">=</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(SOCKADDR);<br /></span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">(</span><span style="color: #000000; ">1</span><span style="color: #000000; ">)<br />{<br />SOCKET&nbsp;sockConn</span><span style="color: #000000; ">=</span><span style="color: #000000; ">accept(sockSrv,(SOCKADDR</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">addrClient,</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">len);</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;接受客户端连接,获取客户端的ip地址</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;sendBuf[</span><span style="color: #000000; ">50</span><span style="color: #000000; ">];<br />sprintf(sendBuf,</span><span style="color: #000000; ">"</span><span style="color: #000000; ">Welcome&nbsp;%s&nbsp;to&nbsp;here!</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,inet_ntoa(addrClient.sin_addr));</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;组合消息发送出去</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">send(sockConn,sendBuf,strlen(sendBuf)</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,</span><span style="color: #000000; ">0</span><span style="color: #000000; ">);</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;发送消息到客户端</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;recvBuf[</span><span style="color: #000000; ">50</span><span style="color: #000000; ">];<br />recv(sockConn,recvBuf,</span><span style="color: #000000; ">50</span><span style="color: #000000; ">,</span><span style="color: #000000; ">0</span><span style="color: #000000; ">);</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;接受客户端消息</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%s\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,recvBuf);<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">closesocket(sockConn);</span><span style="color: #008000; ">//</span><span style="color: #008000; ">断开连接</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">}<br /><br />}</span></div><br />&nbsp;客户端代码<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdio.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Winsock2.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#pragma&nbsp;comment(lib,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">ws2_32.lib</span><span style="color: #000000; ">"</span><span style="color: #000000; ">)<br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;main()<br />{<br />WORD&nbsp;wVersionRequested;<br />WSADATA&nbsp;wsaData;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">WSAata用来存储系统传回的关于WinSocket的资料。</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;err;<br /><br />wVersionRequested&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;MAKEWORD(&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">&nbsp;);<br /><br />err&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;WSAStartup(&nbsp;wVersionRequested,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">wsaData&nbsp;);<br /></span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(&nbsp;err&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">&nbsp;)&nbsp;{<br /></span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">;<br />}<br /><br /></span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(&nbsp;LOBYTE(&nbsp;wsaData.wVersion&nbsp;)&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">1</span><span style="color: #000000; ">||</span><span style="color: #000000; ">HIBYTE(&nbsp;wsaData.wVersion&nbsp;)&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">1</span><span style="color: #000000; ">&nbsp;)&nbsp;<br />{<br />WSACleanup(&nbsp;);<br /></span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">;<br />}<br />SOCKET&nbsp;sockClient</span><span style="color: #000000; ">=</span><span style="color: #000000; ">socket(AF_INET,SOCK_STREAM,</span><span style="color: #000000; ">0</span><span style="color: #000000; ">);</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;AF_INET&nbsp;..tcp连接<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">初始化连接与端口号</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">SOCKADDR_IN&nbsp;addrSrv;<br />addrSrv.sin_addr.S_un.S_addr</span><span style="color: #000000; ">=</span><span style="color: #000000; ">inet_addr(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">127.0.0.1</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);</span><span style="color: #008000; ">//</span><span style="color: #008000; ">本机地址，服务器在本机开启</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">addrSrv.sin_family</span><span style="color: #000000; ">=</span><span style="color: #000000; ">AF_INET;<br />addrSrv.sin_port</span><span style="color: #000000; ">=</span><span style="color: #000000; ">htons(</span><span style="color: #000000; ">6000</span><span style="color: #000000; ">);</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;设置端口号</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">connect(sockClient,(SOCKADDR</span><span style="color: #000000; ">*</span><span style="color: #000000; ">)</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">addrSrv,</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(SOCKADDR));</span><span style="color: #008000; ">//</span><span style="color: #008000; ">连接服务器</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;recvBuf[</span><span style="color: #000000; ">50</span><span style="color: #000000; ">];<br />recv(sockClient,recvBuf,</span><span style="color: #000000; ">50</span><span style="color: #000000; ">,</span><span style="color: #000000; ">0</span><span style="color: #000000; ">);</span><span style="color: #008000; ">//</span><span style="color: #008000; ">接受数据</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%s\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,recvBuf);<br />send(sockClient,</span><span style="color: #000000; ">"</span><span style="color: #000000; ">hello</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,strlen(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">hello</span><span style="color: #000000; ">"</span><span style="color: #000000; ">)</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,</span><span style="color: #000000; ">0</span><span style="color: #000000; ">);</span><span style="color: #008000; ">//</span><span style="color: #008000; ">发送数据</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">closesocket(sockClient);</span><span style="color: #008000; ">//</span><span style="color: #008000; ">关闭连接</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">WSACleanup();<br />}</span></div></p><img src ="http://www.cppblog.com/chenjt3533/aggbug/198226.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenjt3533/" target="_blank">chenjt3533</a> 2013-03-05 13:47 <a href="http://www.cppblog.com/chenjt3533/archive/2013/03/05/198226.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vc++ 数据库编程</title><link>http://www.cppblog.com/chenjt3533/archive/2013/03/05/198225.html</link><dc:creator>chenjt3533</dc:creator><author>chenjt3533</author><pubDate>Tue, 05 Mar 2013 05:41:00 GMT</pubDate><guid>http://www.cppblog.com/chenjt3533/archive/2013/03/05/198225.html</guid><wfw:comment>http://www.cppblog.com/chenjt3533/comments/198225.html</wfw:comment><comments>http://www.cppblog.com/chenjt3533/archive/2013/03/05/198225.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chenjt3533/comments/commentRss/198225.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenjt3533/services/trackbacks/198225.html</trackback:ping><description><![CDATA[<p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "><strong>ODBC</strong>开放数据库互连（Open Database Connectivity）是微软公司开放服务结构（WOSA，Windows Open Services Architecture）中有关数据库的一个组成部分，它建立了一组规范，并提供了一组对数据库访问的标准API（应用程序编程接口）。这些API利用SQL来完成其大部分任务。ODBC本身也提供了对SQL语言的支持，用户可以直接将SQL语句送给ODBC。<br /><br /></p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "><strong>ADO</strong>&nbsp;(ActiveX Data Objects) 是微软公司的一个用于存取数据源的COM组件。它提供了编程语言和统一数据访问方式OLE DB的一个中间层。允许开发人员编写访问数据的代码而不用关心数据库是如何实现的，而只用关心到数据库的连接。访问数据库的时候，关于SQL的知识不是必要的，但是特定数据库支持的SQL命令仍可以通过ADO中的命令对象来执行。ADO被设计来继承微软早期的数据访问对象层，包括RDO (Remote Data Objects) 和DAO(Data Access Objects)。<br /><br /></p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "><strong>使用#import方法对ADO进行操作<br /></strong>在#import中，你需要提供所包含的类型库的路径和名称，它能够自动产生一个对GUIDs的定义，同时对自动生成对ADO对象的封装。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">还能够列举它在类型库中所能找到的类型，对任何你所引用的类型库，VC++会在编译的时候自动生成两个文件:<br />一个头文件（.tlh）,它包含了列举的类型和对类型库中对象的定义。<br />一个实现文件（.tli）对类型库对象模型中的方法产生封装。<br />例<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">#import&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">c:\Program&nbsp;Files\common&nbsp;files\system\ado\msado15.dll</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;no_namespace&nbsp;rename(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">EOF</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,</span><span style="color: #000000; ">"</span><span style="color: #000000; ">adoEOF</span><span style="color: #000000; ">"</span><span style="color: #000000; ">)<br /></span><span style="color: #008000; ">/*</span><span style="color: #008000; ">VC++会自动产生msado15.tlh和msado15.tli两个文件。no_namespace意味着你不需要在初始化变量的时候引用名字空间。对EOF进行该名，是必要的，因为典型的VC++应用都已经定义了EOF作为常数-1</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CoInitialize(NULL);<br /></span><span style="color: #008000; ">/*</span><span style="color: #008000; ">CoInitialize是&nbsp;Windows提供的API函数，用来告诉&nbsp;Windows以单线程的方式创建com对象。参数被保留，且必须为NULL。CoInitialize并不装载COM&nbsp;库，它只用来初始化当前线程使用什么样的套间。使用这个函数后，线程就和一个套间建立了对应关系,线程在此套间运行。CoInitialize和CoUninitialize必须成对使用。</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_ConnectionPtr&nbsp;m_pConnection(_uuidof(Connection));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">使用智能指针产生一个连接指针</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_RecordsetPtr&nbsp;m_pRecordset(_uuidof(Recordset));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">使用智能指针产生一个记录集指针</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">try</span><span style="color: #000000; ">{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pConnection</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">Open(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">DSN=Student</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,</span><span style="color: #000000; ">""</span><span style="color: #000000; ">,</span><span style="color: #000000; ">""</span><span style="color: #000000; ">,</span><span style="color: #000000; ">0</span><span style="color: #000000; ">);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">建立连接，DSN(Data&nbsp;Source&nbsp;Name&nbsp;)是你要连接ODBC数据源的名称</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pRecordset&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;m_pConnection</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">Execute(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">select&nbsp;*&nbsp;from&nbsp;Student</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,NULL,adCmdText);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">执行查询语句</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">(</span><span style="color: #000000; ">!</span><span style="color: #000000; ">m_pRecordset</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">adoEOF)<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_variant_t&nbsp;TheValue;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">_variant_t封装并管理VARIANT数据类型，是COM中使用的数据类型,COM是Component&nbsp;Object&nbsp;Model(组件对象模型)</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TheValue&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;m_pRecordset</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">GetCollect(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">Sname</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">获取表中字段为&#8220;Sname&#8221;的值</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pRecordset</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">MoveNext();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">移动到下一条记录</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;}<br />&nbsp;}</span><span style="color: #0000FF; ">catch</span><span style="color: #000000; ">(_com_error&nbsp;e)<br />&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AfxMessageBox(e.ErrorMessage());<br />&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pRecordset</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">Close();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pConnection</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">Close();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pRecordset&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;NULL;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pConnection&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;NULL;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CoUninitialize();&nbsp;</span></div></p><img src ="http://www.cppblog.com/chenjt3533/aggbug/198225.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenjt3533/" target="_blank">chenjt3533</a> 2013-03-05 13:41 <a href="http://www.cppblog.com/chenjt3533/archive/2013/03/05/198225.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vs2008程序打包</title><link>http://www.cppblog.com/chenjt3533/archive/2012/11/16/195254.html</link><dc:creator>chenjt3533</dc:creator><author>chenjt3533</author><pubDate>Fri, 16 Nov 2012 01:28:00 GMT</pubDate><guid>http://www.cppblog.com/chenjt3533/archive/2012/11/16/195254.html</guid><wfw:comment>http://www.cppblog.com/chenjt3533/comments/195254.html</wfw:comment><comments>http://www.cppblog.com/chenjt3533/archive/2012/11/16/195254.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chenjt3533/comments/commentRss/195254.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenjt3533/services/trackbacks/195254.html</trackback:ping><description><![CDATA[<div clearfix"="" style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; "><h2><span style="font-size: 18px; ">一、创建程序项目<span style="font-weight: normal; ">（含有解决方案）</span></span></h2><h2><span style="font-size: 18px; font-weight: normal; ">例如项目名为MyTest</span></h2></div><div mod-cs-content="" text-content=""  clearfix"="" id="content" sizcache08121602067827913="0" sizset="0" style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; "><p>二、<strong>创建安装项目</strong></p><p>在MyTest解决方案上&#8220;右击&#8221;&#8212;&gt;&#8220;添加&#8221;&#8212;&gt;&#8220;新建项目&#8221;，选择&#8220;其他类型项目&#8221;&#8212;&gt;&#8220;安装和部署&#8221;&#8212;&gt;&#8220;安装项目&#8221;，并命名为&#8220;&nbsp;Install_MyTest&nbsp;&#8221;&nbsp;</p><p>三、<strong>添加项目需要文件</strong>（包括显示在开始菜单中和桌面上快捷方式的图标、卸载程序文件）</p><p>1、在右边的&#8220;应用程序文件夹&#8221;上右击&#8220;添加&#8221;&#8212;&gt;&#8220;项目输出&#8221;，选择 MyTest&nbsp;项目，这样就相当于包含了所有 MyTest&nbsp;&nbsp;的输出文件；</p><p>1、在右边的&#8220;应用程序文件夹&#8221;上右击&#8220;添加&#8221;&#8212;&gt;&#8220;文件&#8221;，选择 MyTest&nbsp;运行需要的所有文件（包括dll、lib、资源文件、配置文件）</p><p>3、在右边的&#8220;应用程序文件夹&#8221;上右击&#8220;添加&#8221;&#8212;&gt;&#8220;文件&#8221;，选择&#8220;c:"windows\system32\msiexec.exe&#8221;文件，用来制作卸载程序；</p><p>4、在右边的&#8220; 应用程序文件夹&nbsp;&#8221;上右击&#8220;添加&#8221;&#8212;&gt;&#8220;文件&#8221;，选择两个*.ico的图标文件，一个作为启动图标、一个卸载图标。</p><p><strong>四、创建快捷方式</strong>（包括开始菜单快捷方式、桌面快捷方式、卸载快捷方式）</p><p>1、开始菜单快捷方式：在&#8220;主输出来自 MyTest&nbsp;(活动)&#8221;上右击&#8220;创建&#8221;主输出来自 MyTest&nbsp;(活动)&#8221;的快捷方式&#8220;，命名为 MyTest&nbsp;，并在其的属性栏中为其&#8220;Icon&#8221;选择刚才导入启动的图标。并将其拖动到&#8220;用户的&#8221;程序&#8221;菜单&#8221;文件下。</p><p>2、桌面快捷方式：步骤同1</p><p>3、卸载快捷方式：在msiexec.exe上右击&#8220;创建msiexec.exe 的快捷方式&#8221;，并命名为&#8220;卸载testwindows&#8221;。将其拖动到&#8220;用户的&#8221;程序&#8221;菜单&#8221;文件下,当然也可放在桌面，将此快捷方式的Argmuments属性设置为&#8221;/x&nbsp;{程序ID}&#8221;，ID值即为打包程序的ProductCode属性,如&#8220;/x {1AE1E45C-C68B-4033-BE53-218FDEEF52D0}&#8221;(不包括双引号)。</p><p><strong>五、打包.net framework</strong></p><p>选择&nbsp;&nbsp;Install_MyTest&nbsp;项目的属性，在对话框中选择&#8220;系统必备&#8221;，然后在弹出的对话框中选择&#8220;从与我的应用程序相同的位置下载系统必备组件&#8221;，确定。</p><p><strong>六、生成</strong></p><p>在 Install_MyTest&nbsp;项目上右击选择&#8220;生成&#8221;，则打包成功，将在你的解决方案文件夹生成一个 Install_MyTest&nbsp;的文件夹，安装文件就在此目录下。</p></div><img src ="http://www.cppblog.com/chenjt3533/aggbug/195254.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenjt3533/" target="_blank">chenjt3533</a> 2012-11-16 09:28 <a href="http://www.cppblog.com/chenjt3533/archive/2012/11/16/195254.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vs2008生成的各种文件</title><link>http://www.cppblog.com/chenjt3533/archive/2012/11/15/195213.html</link><dc:creator>chenjt3533</dc:creator><author>chenjt3533</author><pubDate>Thu, 15 Nov 2012 01:19:00 GMT</pubDate><guid>http://www.cppblog.com/chenjt3533/archive/2012/11/15/195213.html</guid><wfw:comment>http://www.cppblog.com/chenjt3533/comments/195213.html</wfw:comment><comments>http://www.cppblog.com/chenjt3533/archive/2012/11/15/195213.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/chenjt3533/comments/commentRss/195213.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenjt3533/services/trackbacks/195213.html</trackback:ping><description><![CDATA[<div style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; "><div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; "><strong>一、sln文件</strong></span></div><div><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; ">&nbsp; &nbsp; .sln（Solution）</span><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; ">解决方案文件，</span><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; ">表示一个项目组，他通常包含一个项目中所有的工程文件信息。</span></div><div><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; "><br /></span></div><div><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; "><strong>二、suo文件</strong></span></div><div><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; ">&nbsp;&nbsp;&nbsp;&nbsp;suo（Solution User Options）解决方案用户选项文件，记录所有与解决方案建立关联的选项，以便在每次打开时，它都包含用户所做的自定义设置。</span><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; ">.suo文件偶尔会被破坏，从而在构建和编辑应用程序时出现意想不到的结果。如果Visual Studio对于每个解决方案不稳定，就应删除.suo文件。下次打开解决方案时，Visual Studio会重建它。</span></div><div><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; "><br /></span></div><div><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; "><strong>三、vcproj文件</strong></span></div><div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">&nbsp; &nbsp; vcproj（</span><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; ">Visual Studio Project）</span><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; ">vs工程文件，记录</span><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; ">工程中的所有文件信息。</span></div><div><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; "><br /></span></div><div><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; "><strong>四、obj文件</strong></span></div><div><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; ">&nbsp; &nbsp; .obj（Object）</span><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; ">目标文件，</span><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; ">程序编译时生成的中间代码文件，</span><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; ">一般是程序编译后的二进制文件，再通过链接器和资源文件链接就成exe文件了。</span><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; ">OBJ只给出了程序的相对地址，而EXE是绝对地址。</span></div></div><div style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; "></div><strong style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; ">五、pdb文件</strong><div style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; ">&nbsp;&nbsp;&nbsp;&nbsp;pdb（Program Debug Database）程序调试数据库，&nbsp;保存<span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">调试和项目状态信息，从而可以对程序的调试配置进行增量链接。</span>&nbsp;</div><div style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; "></div><div style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; "><strong>六、ncb<span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; ">文件</span></strong></div><span style="text-align: -webkit-auto; font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　NCB（No Compile Browser）无编译浏览文件, NCB为VC++自动创建的跟踪文件，其中存放了供ClassView、WizardBar和Component Gallery使用的信息，由VC开发环境自动生成。无编译浏览文件。当自动完成功能出问题时可以删除此文件。build编译工程后会自动生成。</span><div style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; "><span style="line-height: 24px; "><br /></span></div><div style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; "><span style="line-height: 24px; "><strong>七、idb文件</strong></span></div><div style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; "><span style="line-height: 24px; ">&nbsp; &nbsp; .idb（）文件，MSDev中间层文件<br /></span></div><div style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; "><span style="line-height: 24px; "><br /></span></div><div style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; "><span style="line-height: 24px; "><strong>八、pch文件</strong></span></div><div style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; "><span style="line-height: 24px; ">&nbsp; &nbsp; .pch（</span><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; ">Precompiled Header</span><span style="line-height: 24px; font-family: arial, 宋体, sans-serif; ">）编译头文件，</span><span style="line-height: 24px; ">是存放工程中</span><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; ">预先编译好的</span><span style="line-height: 24px; font-family: arial, 宋体, sans-serif; ">较稳定的代码。</span><span style="line-height: 24px; ">编译器是以文件为单位编译，假设修改了一个文件就要对工程中所有文件重新编译，肯定影响</span><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; ">编译效率。</span><span style="line-height: 24px; font-family: arial, 宋体, sans-serif; ">头文件中所包括的东西往往非常大</span><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; ">（</span><span style="line-height: 24px; font-family: arial, 宋体, sans-serif; ">包括eg.Macro宏,Preprocessor预处理）</span><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; ">，编译将占很长时间，但它们又不常被修改，是较稳定的，因此引入了.PCH文件。</span><span style="line-height: 24px; ">指定一个头文件(.H)，包含我们不会经常修改的代码和其他的头文件，然后用这个头文件(.H)来生成一个预编译头文件(.PCH)，VC默认的头文件就是StdAfx.h，因为头文件是不能编译的，所以我们还需要一个.CPP文件来作桥梁，VC默认的文件为StdAfx.cpp，这个文件里只有一句代码就是:#include "StdAfx.h"。</span><span style="line-height: 24px; font-family: arial, 宋体, sans-serif; ">接下来要用它生成.PCH文件，涉及到几个重要的预编译指令:/Yu,/Yc,/Yx,/Fp，/Yc是用来生成.PCH文件的编译开关，在Project-&gt;setting-&gt;C/C++的Category里的Precompiled Header，然后在左边的树形视图中选择用来编译生成.PCH文件的.CPP文件(默认即StdAfx.cpp)你就可以看到/Yc这个开关，它表示这个文件编译了以后是否生成.PCH文件(可能/Yc的c表示create)，/Fp指令指定生成的.PCH文件的名字及路径(可能/Fp的p代表path)，/Yu的u即use使用，工程中只要包括了.H文件的文件都会有这个/Yu指令，如果选择自动Automatic...的话则原来为/Yc的地方就换成了/Yx指令，且每次编译时编译器会看以前有没有生成过.PCH文件，有则不现生成否则就再次编译产生.PCH文件.。</span></div><div style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; "><span style="line-height: 24px; font-family: arial, 宋体, sans-serif; "><br /></span></div><div style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; "><span style="line-height: 24px; font-family: arial, 宋体, sans-serif; "><strong>九、ilk文件</strong></span></div><div style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; "><span style="line-height: 24px; font-family: arial, 宋体, sans-serif; ">&nbsp; &nbsp;&nbsp;</span><span style="background-color: #ffffff; font-family: arial, 宋体, sans-serif; line-height: 24px; ">链接临时文件。</span></div><img src ="http://www.cppblog.com/chenjt3533/aggbug/195213.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenjt3533/" target="_blank">chenjt3533</a> 2012-11-15 09:19 <a href="http://www.cppblog.com/chenjt3533/archive/2012/11/15/195213.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DLL的创建与调用</title><link>http://www.cppblog.com/chenjt3533/archive/2012/11/14/195178.html</link><dc:creator>chenjt3533</dc:creator><author>chenjt3533</author><pubDate>Wed, 14 Nov 2012 01:35:00 GMT</pubDate><guid>http://www.cppblog.com/chenjt3533/archive/2012/11/14/195178.html</guid><wfw:comment>http://www.cppblog.com/chenjt3533/comments/195178.html</wfw:comment><comments>http://www.cppblog.com/chenjt3533/archive/2012/11/14/195178.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chenjt3533/comments/commentRss/195178.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenjt3533/services/trackbacks/195178.html</trackback:ping><description><![CDATA[<div style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; "><h3><span style="font-size: 14px; ">创建动态链接库 (DLL) 项目：</span></h3><h3><span style="font-size: 14px; font-weight: normal; ">1、从&#8220;文件&#8221;菜单中，选择&#8220;新建&#8221;，然后选择&#8220;项目&#8230;&#8221;。</span></h3><h3><span style="font-size: 14px; font-weight: normal; ">2、在&#8220;项目类型&#8221;窗格中，选择&#8220;Visual C++&#8221;下的&#8220;Win32&#8221;。</span></h3><h3><span style="font-size: 14px; font-weight: normal; ">3、在&#8220;模板&#8221;窗格中，选择&#8220;Win32 控制台应用程序&#8221;。</span></h3><h3><span style="font-size: 14px; font-weight: normal; ">4、为项目选择一个名称，如 MathFuncsDll，并将其键入&#8220;名称&#8221;字段。 为解决方案选择一个名称，如 DynamicLibrary，并将其键入&#8220;解决方案名称&#8221;字段。</span></h3><h3><span style="font-size: 14px; font-weight: normal; ">5、单击&#8220;确定&#8221;启动 Win32 应用程序向导。 在&#8220;Win32 应用程序向导&#8221;对话框的&#8220;概述&#8221;页中，单击&#8220;下一步&#8221;。</span></h3><h3><span style="font-size: 14px; font-weight: normal; ">6、在&#8220;Win32 应用程序向导&#8221;中的&#8220;应用程序设置&#8221;页中，选择&#8220;应用程序类型&#8221;下的&#8220;DLL&#8221;（如果可用），或者选择&#8220;控制台应用程序&#8221;（如果&#8220;DLL&#8221;不可用）。 某些版本的 Visual Studio 不支持通过使用向导创建 DLL 项目。 您可以稍后对此进行更改，以将项目编译为 DLL。</span></h3><h3><span style="font-size: 14px; font-weight: normal; ">7、在&#8220;Win32 应用程序向导&#8221;的&#8220;应用程序设置&#8221;页中，选择&#8220;附加选项&#8221;下的&#8220;空项目&#8221;。</span></h3><h3><span style="font-size: 14px; font-weight: normal; ">8、单击&#8220;完成&#8221;创建项目。</span></h3><h3><span style="font-size: 14px; font-weight: normal; ">9、创建导出的类或函数等，必须在类或函数前加上&nbsp;</span><span style="font-size: 14px; font-weight: normal; ">__declspec(dllexport) 修饰符。 这些修饰符使 DLL 能够导出该类或函数以供其他应用程序使用。</span></h3><h3><strong style="font-size: 14px; ">调用</strong><span style="font-size: 14px; ">动态链接库 (DLL)</span><strong style="font-size: 14px; ">:&nbsp;</strong></h3></div><div style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; ">1、【C++】-&gt;【General】-&gt;【additional&nbsp;include&nbsp;directories】 &nbsp; &nbsp; &nbsp; //&nbsp;&nbsp;添加头文件目录<br />2、【Linker】-&gt;【General】-&gt;【additional&nbsp;library&nbsp;directories】 &nbsp; &nbsp;//&nbsp;&nbsp;添加lib目录<br />3、【linker】-&gt;【input】-&gt;【additional&nbsp;dependencies】&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;// &nbsp;添加lib文件名</div><div style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; "><br /><div><span style="font-family: Simsun; background-color: #ffffff; line-height: 26px; ">将.dll可以放到工程</span><span style="font-family: Simsun; background-color: #ffffff; line-height: 26px; ">生成的exe</span><span style="font-family: Simsun; background-color: #ffffff; line-height: 26px; ">文件夹里面，运行exe就可以直接在当前目录下找到需要的dll文件。（真正的函数的可执行代码都在dll中，lib文件仅仅只是一个索引，而.h文件仅仅只是一个对外的接口）</span>&nbsp;</div></div><div style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; "></div><div style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; "><strong>动态库的三个组成部分</strong></div><div style="font-family: 宋体; line-height: normal; text-align: -webkit-auto; "><div></div><div>.h文件作用 &nbsp;: 声明函数接口</div><div>.lib文件作用: 告诉链接器调用的函数在哪个DLL中</div><div>.dll文件作用: 函数可执行代码</div><div></div><div>.h头文件是编译时必须的，lib是链接时需要的，dll是运行时需要的。完成源代码的编译和链接，有.h和.lib就够了。要使动态连接的程序运行起来，有.dll就够了。在开发和调试阶段，当然最好都有。</div><div></div><div>当我们在自己的程序中引用了一个H文件里的函数,编链器怎么知道该调用哪个DLL文件呢?这就是LIB文件的作用: 告诉链接器 调用的函数在哪个DLL中，函数执行代码在DLL中的什么位置，这也就是为什么需要附加依赖项 .LIB文件，它起到桥梁的作用。如果生成静态库文件，则没有DLL ，只有lib，这时函数可执行代码部分也在lib文件中</div><div></div><div>目前以lib后缀的库有两种，一种为静态链接库(Static Libary，以下简称&#8220;静态库&#8221;)，另一种为动态连接库(DLL，以下简称&#8220;动态库&#8221;)的导入库(Import Libary，以下简称&#8220;导入库&#8221;）。静态库是一个或者多个obj文件的打包，所以有人干脆把从obj文件生成lib的过程称为Archive，即合并到一起。比如你链接一个静态库，如果其中有错，它会准确的找到是哪个obj有错，即静态lib只是壳子。动态库一般会有对应的导入库，方便程序静态载入动态链接库，否则你可能就需要自己LoadLibary调入DLL文件，然后再手工GetProcAddress获得对应函数了。有了导入库，你只需要链接导入库后按照头文件函数接口的声明调用函数就可以了。导入库和静态库的区别很大，他们实质是不一样的东西。静态库本身就包含了实际执行代码、符号表等等，而对于导入库而言，其实际的执行代码位于动态库中，导入库只包含了地址符号表等，确保程序找到对应函数的一些基本地址信息。</div></div><img src ="http://www.cppblog.com/chenjt3533/aggbug/195178.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenjt3533/" target="_blank">chenjt3533</a> 2012-11-14 09:35 <a href="http://www.cppblog.com/chenjt3533/archive/2012/11/14/195178.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>