﻿<?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++博客-inwind-文章分类-C++学习</title><link>http://www.cppblog.com/inwind/category/518.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 19 May 2008 17:13:52 GMT</lastBuildDate><pubDate>Mon, 19 May 2008 17:13:52 GMT</pubDate><ttl>60</ttl><item><title>WordFeatureLib编程笔记</title><link>http://www.cppblog.com/inwind/articles/4247.html</link><dc:creator>inwind</dc:creator><author>inwind</author><pubDate>Thu, 16 Mar 2006 10:45:00 GMT</pubDate><guid>http://www.cppblog.com/inwind/articles/4247.html</guid><wfw:comment>http://www.cppblog.com/inwind/comments/4247.html</wfw:comment><comments>http://www.cppblog.com/inwind/articles/4247.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/inwind/comments/commentRss/4247.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/inwind/services/trackbacks/4247.html</trackback:ping><description><![CDATA[<P>一、小心内存分配，明确每个变量的存储位置<BR>二、算法设计，在尽可能外的循环内执行耗时多的指令<BR>三、小心成员变量的引用传递，防止对内存的多次释放<BR><BR><BR>总之，注意算法设计，小心内存分配。需要加强</P><img src ="http://www.cppblog.com/inwind/aggbug/4247.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/inwind/" target="_blank">inwind</a> 2006-03-16 18:45 <a href="http://www.cppblog.com/inwind/articles/4247.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数组和指针的比较 </title><link>http://www.cppblog.com/inwind/articles/1958.html</link><dc:creator>inwind</dc:creator><author>inwind</author><pubDate>Thu, 22 Dec 2005 05:42:00 GMT</pubDate><guid>http://www.cppblog.com/inwind/articles/1958.html</guid><wfw:comment>http://www.cppblog.com/inwind/comments/1958.html</wfw:comment><comments>http://www.cppblog.com/inwind/articles/1958.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/inwind/comments/commentRss/1958.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/inwind/services/trackbacks/1958.html</trackback:ping><description><![CDATA[1。定义数组变量时必须指定数组元素个数，因为系统会根据元素个数在编译时一次性分配这么多内存；<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 而指针变量只需要指定类型，系统只为该指针变量分配4字节（32位机）内存，而不会为该变量所指内容分配内存。<BR><BR>2。指针变量是有存储空间的；而数组名仅仅是一个标号，没有实际存储空间，单单一个数组名就只能表示该数组的第1个元素的地址。int a[10]; 规定&amp;a就等于&amp;a[0]或者a .<BR><BR>3。例如 char str[]= "hello world"和char *p = "hello world"中，数组str是先分配给他元素个数个内存，然后将后面的字符串复制给这个空间（注意，此时应该考虑\0字符）；而p的建立过程是先在静态存储区建立常字符串"hello world\0"，然后将p指向这个常字符串。所以数组str中元素的内容可以通过重新赋值改变，而p指向的内容不能改变。<img src ="http://www.cppblog.com/inwind/aggbug/1958.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/inwind/" target="_blank">inwind</a> 2005-12-22 13:42 <a href="http://www.cppblog.com/inwind/articles/1958.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C/C+语言struct深层探索 (转自CSDN) </title><link>http://www.cppblog.com/inwind/articles/1753.html</link><dc:creator>inwind</dc:creator><author>inwind</author><pubDate>Wed, 14 Dec 2005 10:27:00 GMT</pubDate><guid>http://www.cppblog.com/inwind/articles/1753.html</guid><wfw:comment>http://www.cppblog.com/inwind/comments/1753.html</wfw:comment><comments>http://www.cppblog.com/inwind/articles/1753.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/inwind/comments/commentRss/1753.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/inwind/services/trackbacks/1753.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1. struct的巨大作用　　面对一个人的大型C/C++程序时，只看其对struct的使用情况我们就可以对其编写者的编程经验进行评估。因为一个大型的C/C++程序，势必要涉及一些(甚至大量)进行数据组合的结构体，这些结构体可以将原本意义属于一个整体的数据组合在一起。从某种程度上来说，会不会用struct，怎样用struct是区别一个开发人员是否具备丰富开发经历的标志。　　在网络协议、通信控制、嵌...&nbsp;&nbsp;<a href='http://www.cppblog.com/inwind/articles/1753.html'>阅读全文</a><img src ="http://www.cppblog.com/inwind/aggbug/1753.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/inwind/" target="_blank">inwind</a> 2005-12-14 18:27 <a href="http://www.cppblog.com/inwind/articles/1753.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vc6函数调用浅析 </title><link>http://www.cppblog.com/inwind/articles/1752.html</link><dc:creator>inwind</dc:creator><author>inwind</author><pubDate>Wed, 14 Dec 2005 10:26:00 GMT</pubDate><guid>http://www.cppblog.com/inwind/articles/1752.html</guid><wfw:comment>http://www.cppblog.com/inwind/comments/1752.html</wfw:comment><comments>http://www.cppblog.com/inwind/articles/1752.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/inwind/comments/commentRss/1752.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/inwind/services/trackbacks/1752.html</trackback:ping><description><![CDATA[今天研究了一下vc6函数调用，看看vc6调用函数时候都做了什么。有些意思。<BR><BR>我写下了如下代码：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;fun(</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)<BR>{<BR>&nbsp;&nbsp;&nbsp;&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">3</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;a</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">b</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">i;<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;main()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;a&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,b</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;result&nbsp;;<BR>&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;fun(</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;result;<BR>}</SPAN></DIV><BR>非常简单。反汇编后(Debug版)变成这样<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">:&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;fun(</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)<BR></SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">:&nbsp;&nbsp;&nbsp;&nbsp;{<BR></SPAN><SPAN style="COLOR: #000000">00401020</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ebp<BR></SPAN><SPAN style="COLOR: #000000">00401021</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ebp,esp<BR></SPAN><SPAN style="COLOR: #000000">00401023</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;sub&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;esp,44h<BR></SPAN><SPAN style="COLOR: #000000">00401026</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ebx<BR></SPAN><SPAN style="COLOR: #000000">00401027</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;esi<BR></SPAN><SPAN style="COLOR: #000000">00401028</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;edi<BR></SPAN><SPAN style="COLOR: #000000">00401029</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;lea&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;edi,[ebp</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">44h]<BR>0040102C&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ecx,11h<BR></SPAN><SPAN style="COLOR: #000000">00401031</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eax,0CCCCCCCCh<BR></SPAN><SPAN style="COLOR: #000000">00401036</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;rep&nbsp;stos&nbsp;&nbsp;&nbsp;&nbsp;dword&nbsp;ptr&nbsp;[edi]<BR></SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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">3</SPAN><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #000000">00401038</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dword&nbsp;ptr&nbsp;[ebp</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">4</SPAN><SPAN style="COLOR: #000000">],</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #000000">4</SPAN><SPAN style="COLOR: #000000">:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;a</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">b</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">i;<BR>0040103F&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eax,dword&nbsp;ptr&nbsp;[ebp</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">8</SPAN><SPAN style="COLOR: #000000">]<BR></SPAN><SPAN style="COLOR: #000000">00401042</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;add&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eax,dword&nbsp;ptr&nbsp;[ebp</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">0Ch]<BR></SPAN><SPAN style="COLOR: #000000">00401045</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;add&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eax,dword&nbsp;ptr&nbsp;[ebp</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">4</SPAN><SPAN style="COLOR: #000000">]<BR></SPAN><SPAN style="COLOR: #000000">5</SPAN><SPAN style="COLOR: #000000">:&nbsp;&nbsp;&nbsp;&nbsp;}<BR>00401048&nbsp;&nbsp; pop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edi<BR>00401049&nbsp;&nbsp; pop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; esi<BR>0040104A&nbsp;&nbsp; pop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebx<BR>0040104B&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; esp,ebp<BR>0040104D&nbsp;&nbsp; pop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp<BR>0040104E&nbsp;&nbsp; ret<BR><BR></SPAN><SPAN style="COLOR: #000000">7</SPAN><SPAN style="COLOR: #000000">:&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;main()<BR></SPAN><SPAN style="COLOR: #000000">8</SPAN><SPAN style="COLOR: #000000">:&nbsp;&nbsp;&nbsp;&nbsp;{<BR></SPAN><SPAN style="COLOR: #000000">00401060</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ebp<BR></SPAN><SPAN style="COLOR: #000000">00401061</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ebp,esp<BR></SPAN><SPAN style="COLOR: #000000">00401063</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;sub&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;esp,4Ch<BR></SPAN><SPAN style="COLOR: #000000">00401066</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ebx<BR></SPAN><SPAN style="COLOR: #000000">00401067</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;esi<BR></SPAN><SPAN style="COLOR: #000000">00401068</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;edi<BR></SPAN><SPAN style="COLOR: #000000">00401069</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;lea&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;edi,[ebp</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">4Ch]<BR>0040106C&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ecx,13h<BR></SPAN><SPAN style="COLOR: #000000">00401071</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eax,0CCCCCCCCh<BR></SPAN><SPAN style="COLOR: #000000">00401076</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;rep&nbsp;stos&nbsp;&nbsp;&nbsp;&nbsp;dword&nbsp;ptr&nbsp;[edi]<BR></SPAN><SPAN style="COLOR: #000000">9</SPAN><SPAN style="COLOR: #000000">:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;a&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,b</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #000000">00401078</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dword&nbsp;ptr&nbsp;[ebp</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">4</SPAN><SPAN style="COLOR: #000000">],</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000"><BR>0040107F&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dword&nbsp;ptr&nbsp;[ebp</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">8</SPAN><SPAN style="COLOR: #000000">],</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #000000">10</SPAN><SPAN style="COLOR: #000000">:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;result&nbsp;;<BR></SPAN><SPAN style="COLOR: #000000">11</SPAN><SPAN style="COLOR: #000000">:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;fun(</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #000000">00401086</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #000000">00401088</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000"><BR>0040108A&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@ILT</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">5</SPAN><SPAN style="COLOR: #000000">(fun)&nbsp;(0040100a)<BR>0040108F&nbsp;&nbsp;&nbsp;add&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;esp,</SPAN><SPAN style="COLOR: #000000">8</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #000000">00401092</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dword&nbsp;ptr&nbsp;[ebp</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">0Ch],eax<BR></SPAN><SPAN style="COLOR: #000000">12</SPAN><SPAN style="COLOR: #000000">:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;result;<BR></SPAN><SPAN style="COLOR: #000000">00401095</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eax,dword&nbsp;ptr&nbsp;[ebp</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">0Ch]<BR></SPAN><SPAN style="COLOR: #000000">13</SPAN><SPAN style="COLOR: #000000">:&nbsp;&nbsp;&nbsp;}<BR></SPAN><SPAN style="COLOR: #000000">00401098</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;pop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;edi<BR></SPAN><SPAN style="COLOR: #000000">00401099</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;pop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;esi<BR>0040109A&nbsp;&nbsp;&nbsp;pop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ebx<BR>0040109B&nbsp;&nbsp;&nbsp;add&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;esp,4Ch<BR>0040109E&nbsp;&nbsp;&nbsp;cmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ebp,esp<BR>004010A0&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__chkesp&nbsp;(004010c0)<BR>004010A5&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;esp,ebp<BR>004010A7&nbsp;&nbsp;&nbsp;pop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ebp<BR>004010A8&nbsp;&nbsp;&nbsp;ret</SPAN></DIV><BR>我们主要来看看函数调用部分<BR><BR><STRONG>1.参数压栈</STRONG><BR>push 2<BR>push 1<BR>参数从右向左压栈(__cdcel),esp递减<BR><BR><STRONG>2.调用函数</STRONG><BR>&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @ILT+5(fun) (0040100a)<BR>这条指令会把下一行代码的地址压栈，也就是函数返回地址。同时跳转到函数入口处<BR><BR><STRONG>3.进入函数体</STRONG><BR>push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp<BR>mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp,esp<BR>首先保存ebp的地址，然后把esp保存到ebp中去<BR>00401023&nbsp;&nbsp; sub&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; esp,44h<BR>00401026&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebx<BR>00401027&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; esi<BR>00401028&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edi<BR>减小stack的指针(注意，stack是从内存的高端向低端生长的)，为局部变量保留一些空间，这里的44h不是固定的，由编译器计算得来<BR>00401029&nbsp;&nbsp; lea&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edi,[ebp-44h]<BR>0040102C&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ecx,11h<BR>00401031&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,0CCCCCCCCh<BR>00401036&nbsp;&nbsp; rep stos&nbsp;&nbsp;&nbsp; dword ptr [edi]<BR>用0xCC填充局部变量空间。这是Debug模式特有的，如果是字符串，你就看到被初始化成"烫烫烫烫烫烫"<BR>至此，整个堆栈变成<BR>|-----------------|<BR>|&nbsp;&nbsp;&nbsp; 局部变量2&nbsp;&nbsp; |<BR>|-----------------|<BR>|&nbsp;&nbsp;&nbsp; 局部变量1&nbsp;&nbsp;&nbsp; |&lt;----ebp-4<BR>|-----------------|<BR>|&nbsp;&nbsp;&nbsp; old ebp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&lt;----ebp<BR>|-----------------|<BR>| 函数返回地址| &lt;----ebp+4<BR>|-----------------|<BR>|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 参数1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;| &lt;----ebp+8<BR>|-----------------|<BR>|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 参数2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<BR>|-----------------|<BR><BR>Next:<BR>int i = 3;<BR>00401038&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp-4],3<BR>这里你看到[ebp-4]就是第一个局部变量i了<BR>0040103F&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,dword ptr [ebp+8]<BR>00401042&nbsp;&nbsp; add&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,dword ptr [ebp+0Ch]<BR>00401045&nbsp;&nbsp; add&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,dword ptr [ebp-4]<BR>[ebp+8],[ebp+0Ch]分别是a和b了<BR><BR><STRONG>4.函数返回</STRONG><BR>函数的结果都是放在eax中(ps:你可以在vc的watch窗口输入@EAX，就可以直接看到函数返回值了）<BR>00401048&nbsp;&nbsp; pop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edi<BR>00401049&nbsp;&nbsp; pop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; esi<BR>0040104A&nbsp;&nbsp; pop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebx<BR>0040104B&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; esp,ebp<BR>0040104D&nbsp;&nbsp; pop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp<BR>0040104E&nbsp;&nbsp; ret<BR>把edi,esi,ebx恢复，然后恢复esp,ebp,这时函数的返回地址就在栈顶，调用ret就可以返回了。<BR><BR><BR>那如果改变函数的返回地址会怎样？<BR>ok,我们修改一下代码：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><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></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;fun2()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">fun2()&nbsp;called</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;fun(</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)<BR>{<BR>&nbsp;&nbsp;&nbsp;&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">3</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">return&nbsp;address:0x%x\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">i</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">fun2&nbsp;address:0x%x\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">fun2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">int&nbsp;*p&nbsp;=&nbsp;(int*)&amp;fun2;<BR>&nbsp;&nbsp;&nbsp;&nbsp;__asm<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;ebx,p<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;dword&nbsp;ptr[ebp+4],ebx<BR>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">i</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">fun2;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">modify&nbsp;return&nbsp;address</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;a</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">b</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">i;<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;main()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;a&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,b</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;result&nbsp;;<BR>&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;fun(</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;result;<BR>}</SPAN></DIV><BR>Wow,这时，我们就会发现fun2被调用了。这就是Buffer overrun(缓冲溢出)所做的事情吧。<BR><BR><BR><STRONG>5.最后一步，调用者调整堆栈指针</STRONG><BR>call&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @ILT+5(fun) (0040100a)<BR>&nbsp;add&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; esp,8<BR>为什么要调整呢，因为调用之前push两个参数进入栈，现在要恢复它<BR>&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp-0Ch],eax<BR>这句话就是享用函数调用的果实了(EAX保存了函数的返回值)<BR><BR><img src ="http://www.cppblog.com/inwind/aggbug/1752.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/inwind/" target="_blank">inwind</a> 2005-12-14 18:26 <a href="http://www.cppblog.com/inwind/articles/1752.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>函数对象</title><link>http://www.cppblog.com/inwind/articles/1751.html</link><dc:creator>inwind</dc:creator><author>inwind</author><pubDate>Wed, 14 Dec 2005 10:24:00 GMT</pubDate><guid>http://www.cppblog.com/inwind/articles/1751.html</guid><wfw:comment>http://www.cppblog.com/inwind/comments/1751.html</wfw:comment><comments>http://www.cppblog.com/inwind/articles/1751.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/inwind/comments/commentRss/1751.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/inwind/services/trackbacks/1751.html</trackback:ping><description><![CDATA[<P>函数指针的一种替代策略是Function object（函数对象）。</P>
<P>函数对象与函数指针相比较有两个方面的优点：首先如果被重载的调用操作符是inline函数则编译器能够执行内联编译，提供可能的性能好处；其次函数对象可以拥有任意数目的额外数据，用这些数据可以缓冲结果，也可以缓冲有助于当前操作的数据。</P>
<P>函数对象是一个类，它重载了函数调用操作符operator() ,该操作符封装了一个函数的功能。典型情况下函数对象被作为实参传递给泛型算法，当然我们也可以定义独立的函数对象实例。</P>
<P>来看下面的二个例子： 比较理解会更好些：</P>
<P>#include&lt;vector&gt;<BR>#include&lt;string&gt;<BR>#include&lt;iostream&gt;<BR>#include&lt;algorithm&gt;<BR>using namespace std;<BR>class Sum {<BR>int val;<BR>public:<BR>Sum(int i) :val(i) { }<BR><BR>//当在需要int的地方，Sum将自动转换为int类型<BR>//这里是为了方便cout&lt;&lt;Sum的实例；<BR>operator int() const { return val; } <BR><BR>//写在类中的函数代码一般默认为内联代码<BR>int operator()(int i) { return val+=i; }<BR>};<BR><BR>void f(vector&lt;int&gt; v)<BR>{<BR style="COLOR: rgb(255,0,0)"><SPAN style="COLOR: rgb(255,255,255); BACKGROUND-COLOR: rgb(0,0,0)"><FONT style="BACKGROUND-COLOR: #ffffff" color=#000000>Sum s = 0; //Sum s = 0等价于Sum s(0),不等价于Sum s;s = 0;</FONT></SPAN><BR><BR>//对vector&lt;int&gt;中的元素求和<BR>//函数对象被作为实参传递给泛型算法<BR>s = for_each(v.begin(), v.end(), s); <BR><BR>cout &lt;&lt; "the sum is " &lt;&lt; s &lt;&lt; "\n";<BR><BR>//更简单的写法，定义独立的函数对象实例<BR>cout &lt;&lt; "the sum is " &lt;&lt; for_each(v.begin(), v.end(), Sum(0)) &lt;&lt; "\n";<BR>}<BR><BR><BR>int main()<BR>{<BR>vector&lt;int&gt; v;<BR>v.push_back(3); v.push_back(2); v.push_back(1);<BR>f(v);<BR>system("pause");<BR>return 0;<BR>}<BR>－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<BR>#include &lt;iostream&gt;<BR>#include &lt;list&gt;<BR>#include &lt;algorithm&gt;<BR>#include "print.hpp"<BR>using namespace std;</P>
<P>// function object that adds the value with which it is initialized<BR>class AddValue {<BR>&nbsp; private:<BR>&nbsp;&nbsp;&nbsp; int theValue;&nbsp;&nbsp;&nbsp; // the value to add<BR>&nbsp; public:<BR>&nbsp;&nbsp;&nbsp; // constructor initializes the value to add<BR>&nbsp;&nbsp;&nbsp; AddValue(int v) : theValue(v) {<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; // the ``function call'' for the element adds the value<BR>&nbsp;&nbsp;&nbsp; void operator() (int&amp; elem) const {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elem += theValue;<BR>&nbsp;&nbsp;&nbsp; }<BR>};</P>
<P>int main()<BR>{<BR>&nbsp;&nbsp;&nbsp; list&lt;int&gt; coll;</P>
<P>&nbsp;&nbsp;&nbsp; // insert elements from 1 to 9<BR>&nbsp;&nbsp;&nbsp; for (int i=1; i&lt;=9; ++i) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; coll.push_back(i);<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; PRINT_ELEMENTS(coll,"initialized:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ");</P>
<P>&nbsp;&nbsp;&nbsp; // add value 10 to each element<BR>&nbsp;&nbsp;&nbsp; for_each (coll.begin(), coll.end(),&nbsp;&nbsp;&nbsp; // range<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AddValue(10));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // operation</P>
<P>&nbsp;&nbsp;&nbsp; PRINT_ELEMENTS(coll,"after adding 10:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ");</P>
<P>&nbsp;&nbsp;&nbsp; // add value of first element to each element<BR>&nbsp;&nbsp;&nbsp; for_each (coll.begin(), coll.end(),&nbsp;&nbsp;&nbsp; // range<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AddValue(*coll.begin()));&nbsp;&nbsp;&nbsp; // operation</P>
<P>&nbsp;&nbsp;&nbsp; PRINT_ELEMENTS(coll,"after adding first element: ");<BR>}<BR>-------------------------------------------------------------------------<BR>operator()中的参数为container中的元素<BR>－－－－－－－－－－－－－－－－－－－－－－－－－－－<BR><BR>另外的实例：<BR>Function Objects as Sorting Criteria</P>
<P class=docText>Programmers often need a sorted collection of elements that have a special class (for example, a collection of <TT>persons</TT>). However, you either don't want to use or you can't use the usual operator <TT>&lt;</TT> to sort the objects. Instead, you sort the objects according to a special sorting criterion based on some member function. In this regard, a function object can help. Consider the following example:</P><PRE>   <SPAN class=docEmphasis>// fo/sortl.cpp</SPAN>

   #include &lt;iostream&gt;
   #include &lt;string&gt;
   #include &lt;set&gt;
   #include &lt;algorithm&gt;
   using namespace std;


   class Person {
     public:
       string firstname() const;
       string lastname() const;
       ...
   };


   <SPAN class=docEmphasis>/* class for function predicate</SPAN>
    <SPAN class=docEmphasis>* - operator</SPAN>() <SPAN class=docEmphasis>returns whether a person is less than another person</SPAN>
    <SPAN class=docEmphasis>*/</SPAN>
   class PersonSortCriterion {
     public:
       bool operator() (const Person&amp; p1, const Person&amp; p2) const {
           <SPAN class=docEmphasis>/* a person is less than another person</SPAN>
            <SPAN class=docEmphasis>* - if the last name is less</SPAN>
            <SPAN class=docEmphasis>* - if the last name is equal and the first name is less</SPAN>
            <SPAN class=docEmphasis>*/</SPAN>
           return p1.lastname()&lt;p2.1astname() ||
                  (! (p2.1astname()&lt;p1.lastname()) &amp;&amp;
                   p1.firstname()&lt;p2.firstname());
       }
   };


   int main()
   {

<SPAN class=docEmphasis>       //declare set type with special sorting criterion</SPAN>
       typedef set&lt;Person,PersonSortCriterion&gt; PersonSet;

       <SPAN class=docEmphasis>//create such a collection</SPAN>
       PersonSet coll;
       ...


       <SPAN class=docEmphasis>//do something with the elements</SPAN>
       PersonSet::iterator pos;
       for (pos = coll.begin(); pos != coll.end();++pos) {
           ...
       }
       ...
   }<BR><PRE><BR><BR>   <SPAN class=docEmphasis>//fo/foreach3.cpp</SPAN>

   #include &lt;iostream&gt;
   #include &lt;vector&gt;
   #include &lt;algorithm&gt;
   using namespace std;


   <SPAN class=docEmphasis>//function object to process the mean value</SPAN>
   class MeanValue {
     private:
       long num;     <SPAN class=docEmphasis>//number of elements</SPAN>
       long sum;     <SPAN class=docEmphasis>//sum of all element values</SPAN>
     public:
       <SPAN class=docEmphasis>//constructor</SPAN>
       MeanValue() : num(0), sum(0) {
       }


       <SPAN class=docEmphasis>//"function call"</SPAN>
       <SPAN class=docEmphasis>//-process one more element of the sequence</SPAN>
       void operator() (int elem) {
           num++;          <SPAN class=docEmphasis>//increment count</SPAN>
           sum += elem;    <SPAN class=docEmphasis>//add value</SPAN>
       }


       <SPAN class=docEmphasis>//return mean value</SPAN>
       double value() {
           return static_cast&lt;double&gt;(sum) / static_cast&lt;double&gt;(num);
       }
   };


   int  main()
   {
        vector&lt;int&gt; coll;


        <SPAN class=docEmphasis>//insert elments from</SPAN> 1 <SPAN class=docEmphasis>to</SPAN> 8
        for (int i=1; i&lt;=8; ++i) {
            coll.push_back(i);
        }


        <SPAN class=docEmphasis>//process and print mean value</SPAN>
        MeanValue mv = for_each (coll.begin(), coll.end(), <SPAN class=docEmphasis>//range</SPAN>
                                 MeanValue());             <SPAN class=docEmphasis>//operation</SPAN>
        cout &lt;&lt; "mean value: " &lt;&lt; mv.value() &lt;&lt; endl;
   }</PRE></PRE><img src ="http://www.cppblog.com/inwind/aggbug/1751.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/inwind/" target="_blank">inwind</a> 2005-12-14 18:24 <a href="http://www.cppblog.com/inwind/articles/1751.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++的4种类型转换</title><link>http://www.cppblog.com/inwind/articles/1585.html</link><dc:creator>inwind</dc:creator><author>inwind</author><pubDate>Wed, 07 Dec 2005 02:50:00 GMT</pubDate><guid>http://www.cppblog.com/inwind/articles/1585.html</guid><wfw:comment>http://www.cppblog.com/inwind/comments/1585.html</wfw:comment><comments>http://www.cppblog.com/inwind/articles/1585.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/inwind/comments/commentRss/1585.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/inwind/services/trackbacks/1585.html</trackback:ping><description><![CDATA[<DIV><STRONG>&nbsp;&nbsp; 一、C 风格（C-style）强制转型如下：</STRONG> </DIV>
<P>&nbsp;&nbsp;&nbsp; (T) expression // cast expression to be of type T <BR>&nbsp;&nbsp;&nbsp; 函数风格（Function-style）强制转型使用这样的语法：<BR>&nbsp;&nbsp;&nbsp; T(expression) // cast expression to be of type T <BR>&nbsp;&nbsp;&nbsp; 这两种形式之间没有本质上的不同，它纯粹就是一个把括号放在哪的问题。我把这两种形式称为旧风格（old-style）的强制转型。 </P>
<P><STRONG>&nbsp;&nbsp;&nbsp;二、 C++的四种强制转型形式：</STRONG></P>
<P>　　C++ 同时提供了四种新的强制转型形式（通常称为新风格的或 C++ 风格的强制转型）： <BR>　　const_cast(expression) <BR>　　dynamic_cast(expression) <BR>　　reinterpret_cast(expression) <BR>　　static_cast(expression) </P>
<P>　　每一种适用于特定的目的： </P>
<P>　　dynamic_cast 主要用于执行“安全的向下转型（safe downcasting）”，也就是说，要确定一个对象是否是一个继承体系中的一个特定类型。它是唯一不能用旧风格语法执行的强制转型，也是唯一可能有重大运行时代价的强制转型。<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; static_cast 可以被用于强制隐型转换（例如，non-const 对象转型为 const 对象，int 转型为 double，等等），它还可以用于很多这样的转换的反向转换（例如，void* 指针转型为有类型指针，基类指针转型为派生类指针），但是它不能将一个 const 对象转型为 non-const 对象（只有 const_cast 能做到），它最接近于C-style的转换。<BR>&nbsp;&nbsp;&nbsp; <BR>　　 const_cast 一般用于强制消除对象的常量性。它是唯一能做到这一点的 C++ 风格的强制转型。 </P>
<P>　　 reinterpret_cast 是特意用于底层的强制转型，导致实现依赖（implementation-dependent）（就是说，不可移植）的结果，例如，将一个指针转型为一个整数。这样的强制转型在底层代码以外应该极为罕见。<BR>　　<BR>　　旧风格的强制转型依然合法，但是新的形式更可取。首先，在代码中它们更容易识别（无论是人还是像 grep 这样的工具都是如此），这样就简化了在代码中寻找类型系统被破坏的地方的过程。第二，更精确地指定每一个强制转型的目的，使得编译器诊断使用错误成为可能。例如，如果你试图使用一个 const_cast 以外的新风格强制转型来消除常量性，你的代码将无法编译。 </P>
<P>==&nbsp; <BR><STRONG>==&nbsp; dynamic_cast .vs. static_cast</STRONG> <BR>==</P>
<DIV>
<P>class B { ... };<BR>class D : public B { ... };</P>
<P>void f(B* pb)<BR>{<BR>&nbsp;&nbsp; D* pd1 = dynamic_cast&lt;D*&gt;(pb);<BR>&nbsp;&nbsp; D* pd2 = static_cast&lt;D*&gt;(pb);<BR>}</P>
<P>If pb really points to an object of type D, then pd1 and pd2 will get the same value. They will also get the same value if pb == 0. </P>
<P>If pb points to an object of type B and not to the complete D class, then dynamic_cast will know enough to return zero. However, static_cast relies on the programmer’s assertion that pb points to an object of type D and simply returns a pointer to that supposed D object.</P></DIV>
<P>&nbsp;&nbsp;&nbsp; 即dynamic_cast可用于继承体系中的向下转型，即将基类指针转换为派生类指针，比static_cast更严格更安全。dynamic_cast在执行效率上比static_cast要差一些,但static_cast在更宽上范围内可以完成映射,这种不加限制的映射伴随着不安全性.static_cast覆盖的变换类型除类层次的静态导航以外,还包括无映射变换,窄化变换(这种变换会导致对象切片,丢失信息),用VOID*的强制变换,隐式类型变换等...</P>
<P><BR>==<BR><STRONG>==&nbsp; static_cast .vs. reinterpret_cast</STRONG> <BR>==</P>
<P>&nbsp;&nbsp;&nbsp; reinterpret_cast是为了映射到一个完全不同类型的意思,这个关键词在我们需要把类型映射回原有类型时用到它.我们映射到的类型仅仅是为了故弄玄虚和其他目的,这是所有映射中最危险的.(这句话是C++编程思想中的原话)</P>
<P>&nbsp;&nbsp;&nbsp; static_cast 和 reinterpret_cast 操作符修改了操作数类型. 它们不是互逆的; static_cast 在编译时使用类型信息执行转换, 在转换执行必要的检测(诸如指针越界计算, 类型检查). 其操作数相对是安全的. 另一方面, reinterpret_cast 仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换, 例子如下:</P>
<P>&nbsp;&nbsp;&nbsp; int n=9; double d=static_cast &lt; double &gt; (n); </P>
<P>&nbsp;&nbsp;&nbsp; 上面的例子中, 我们将一个变量从 int 转换到 double. 这些类型的二进制表达式是不同的. 要将整数 9 转换到 双精度整数 9, static_cast 需要正确地为双精度整数 d 补足比特位. 其结果为 9.0. 而reinterpret_cast 的行为却不同: </P>
<P>&nbsp;&nbsp;&nbsp; int n=9;<BR>&nbsp;&nbsp;&nbsp; double d=reinterpret_cast&lt;double &amp; &gt; (n); </P>
<P>&nbsp;&nbsp;&nbsp; 这次, 结果有所不同. 在进行计算以后, d 包含无用值. 这是因为 reinterpret_cast 仅仅是复制 n 的比特位到 d, 没有进行必要的分析. </P><img src ="http://www.cppblog.com/inwind/aggbug/1585.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/inwind/" target="_blank">inwind</a> 2005-12-07 10:50 <a href="http://www.cppblog.com/inwind/articles/1585.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>