﻿<?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++博客- 攀升·Uranus-随笔分类-C/C++</title><link>http://www.cppblog.com/iuranus/category/4275.html</link><description>&lt;br&gt;&lt;font color="#ADFF2F"&gt;Something Different，Something New&lt;/font&gt;</description><language>zh-cn</language><lastBuildDate>Thu, 06 May 2010 09:44:37 GMT</lastBuildDate><pubDate>Thu, 06 May 2010 09:44:37 GMT</pubDate><ttl>60</ttl><item><title>(转)C++程序调用C函数</title><link>http://www.cppblog.com/iuranus/archive/2010/03/08/109187.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Mon, 08 Mar 2010 07:23:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2010/03/08/109187.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/109187.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2010/03/08/109187.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/109187.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/109187.html</trackback:ping><description><![CDATA[<p>转自：<a href="http://blog.csdn.net/ustcgy/archive/2009/12/23/5063082.aspx">http://blog.csdn.net/ustcgy/archive/2009/12/23/5063082.aspx</a><br><br>这种需求很多,又因为C++和C是两种完全不同的编译链接处理方式,所以要稍加处理.总结大致有两大类实现方法.</p>
<p>文中给出的是完整的,具体的,但又最基本最简单的实现,至于理论性的东西在网上很容易搜索的到.</p>
<p><strong>一.通过处理被调用的C头文件</strong></p>
<p><span style="COLOR: rgb(0,0,255)">a.h:</span></p>
<p>#ifndef __A_H<br>#define __A_H</p>
<p>#ifdef __cplusplus<br>extern "C" {<br>#endif</p>
<p>int ThisIsTest(int a, int b);</p>
<p>#ifdef __cplusplus<br>}<br>#endif</p>
<p>#endif</p>
<p><span style="COLOR: rgb(0,0,255)">a.c:</span></p>
<p>#include "a.h"</p>
<p>int ThisIsTest(int a, int b) {<br>&nbsp; return (a + b);<br>}</p>
<p><span style="COLOR: rgb(0,0,255)">aa.h:</span></p>
<p>class AA {<br>&nbsp; public:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int bar(int a, int b);<br>};</p>
<p><span style="COLOR: rgb(0,0,255)">aa.cpp:</span></p>
<p>#include "a.h"<br>#include "aa.h"<br>#include "stdio.h"</p>
<p>int AA::bar(int a, int b){ <br>&nbsp;&nbsp;&nbsp; printf("result=%d\n", ThisIsTest(a, b)); <br>&nbsp;&nbsp;&nbsp; return 0;<br>}</p>
<p><span style="COLOR: rgb(0,0,255)">main.cpp:</span></p>
<p>#include "aa.h"</p>
<p>int main(int argc, char **argv){ <br>&nbsp; int a = 1; <br>&nbsp; int b = 2; <br>&nbsp; AA* aa = new AA(); <br>&nbsp; aa-&gt;bar(a, b); <br>&nbsp; delete(aa);<br>&nbsp; return(0); <br>}</p>
<p><span style="COLOR: rgb(0,0,255)">Makefile:</span></p>
<p>all:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gcc -Wall -c a.c -o a.o<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gcc -Wall -c aa.cpp -o aa.o<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gcc -Wall -c main.cpp -o main.o<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; g++ -o test *.o</p>
<p><strong>二. 通过处理调用的C++文件</strong></p>
<p>恢复a.h文件为一般性C头文件,在aa.cpp文件中extern包含a.h头文件或函数.</p>
<p><span style="COLOR: rgb(0,0,255)">a.h:</span></p>
<p>#ifndef __A_H<br>#define __A_H<br>int ThisIsTest(int a, int b);<br>#endif</p>
<p><span style="COLOR: rgb(0,0,255)">aa.cpp:</span></p>
<p>extern "C"<br>{<br>&nbsp;&nbsp;&nbsp; #include "a.h"<br>}<br>#include "aa.h"<br>#include "stdio.h"</p>
<p>int AA::bar(int a, int b){ <br>&nbsp;&nbsp;&nbsp; printf("result=%d\n", ThisIsTest(a, b)); <br>&nbsp;&nbsp;&nbsp; return 0;<br>}</p>
<p>or</p>
<p><span style="COLOR: rgb(0,0,255)">aa.cpp:</span></p>
<p>#include "aa.h"<br>#include "stdio.h"</p>
<p>extern "C"<br>{<br>&nbsp;&nbsp;&nbsp; int ThisIsTest(int a, int b);<br>}</p>
<p>int AA::bar(int a, int b){ <br>&nbsp;&nbsp;&nbsp; printf("result=%d\n", ThisIsTest(a, b)); <br>&nbsp;&nbsp;&nbsp; return 0;<br>}</p>
<img src ="http://www.cppblog.com/iuranus/aggbug/109187.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2010-03-08 15:23 <a href="http://www.cppblog.com/iuranus/archive/2010/03/08/109187.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转) 总结C++中的所有强制转换函数(const_cast，reinterpret_cast，static_cast，dynamic_cast) </title><link>http://www.cppblog.com/iuranus/archive/2009/06/22/88257.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Mon, 22 Jun 2009 03:24:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2009/06/22/88257.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/88257.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2009/06/22/88257.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/88257.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/88257.html</trackback:ping><description><![CDATA[url: http://doserver.net/post/static_cast-const_cast-reinterpret_cast-dynamic_cast.php
<br><br>非常抱歉，谢谢郭老师的指正，我没有认真看这个文章就转过来了，其实他的错误太多了，而且还是致命的，对大家不负责任了，请大家谅解！现在是修正版本，基本没有错误了！如果觉得还有问题，请联系我，谢谢你的关注！<br>这篇文章其实并不是不才的原创，本来打算自己写的，但是通过baidu一下，发现有兄弟写出来了，就干脆摘录下来，供大家参考使用了！<br>详情请看：<br><a name="entrymore"></a>
<div class="dp-highlighter">
<div class="bar">
<div class="tools"><a href="http://doserver.net/#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://doserver.net/#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://doserver.net/#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div>
</div>
<ol class="dp-cpp" start="1">
    <li class="alt">标准c++中主要有四种强制转换类型运算符：&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">const_cast，reinterpret_cast，static_cast，dynamic_cast等等。&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">1）static_cast&lt;T*&gt;(a)&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">将地址a转换成类型T，T和a必须是指针、引用、算术类型或枚举类型。&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">表达式static_cast&lt;T*&gt;(a),&nbsp;a的值转换为模板中指定的类型T。在运行时转换过程中，不进行类型检查来确保转换的安全性。&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">例子：&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">class&nbsp;B&nbsp;{&nbsp;...&nbsp;};&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">class&nbsp;D&nbsp;:&nbsp;public&nbsp;B&nbsp;{&nbsp;...&nbsp;};&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">void&nbsp;f(B*&nbsp;pb,&nbsp;D*&nbsp;pd)&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">{&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;&nbsp;D*&nbsp;pd2&nbsp;=&nbsp;static_cast&lt;D*&gt;(pb);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;不安全,&nbsp;pb可能只是B的指针&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;B*&nbsp;pb2&nbsp;=&nbsp;static_cast&lt;B*&gt;(pd);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;安全的&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">}&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">class&nbsp;B&nbsp;{&nbsp;...&nbsp;};&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">class&nbsp;D&nbsp;:&nbsp;public&nbsp;B&nbsp;{&nbsp;...&nbsp;};&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">void&nbsp;f(B*&nbsp;pb,&nbsp;D*&nbsp;pd)&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">{&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;D*&nbsp;pd2&nbsp;=&nbsp;static_cast&lt;D*&gt;(pb);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;不安全,&nbsp;pb可能只是B的指针&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;&nbsp;B*&nbsp;pb2&nbsp;=&nbsp;static_cast&lt;B*&gt;(pd);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;安全的&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">}&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">class&nbsp;B&nbsp;{&nbsp;...&nbsp;};&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">class&nbsp;D&nbsp;:&nbsp;public&nbsp;B&nbsp;{&nbsp;...&nbsp;};&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">void&nbsp;f(B*&nbsp;pb,&nbsp;D*&nbsp;pd)&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">{&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;&nbsp;D*&nbsp;pd2&nbsp;=&nbsp;static_cast&lt;D*&gt;(pb);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;不安全,&nbsp;pb可能只是B的指针&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;B*&nbsp;pb2&nbsp;=&nbsp;static_cast&lt;B*&gt;(pd);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;安全的&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">}&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">2）dynamic_cast&lt;T*&gt;(a)&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">完成类层次结构中的提升。T必须是一个指针、引用或无类型的指针。a必须是决定一个指针或引用的表达式。&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">表达式dynamic_cast&lt;T*&gt;(a)&nbsp;将a值转换为类型为T的对象指针。如果类型T不是a的某个基类型，该操作将返回一个空指针。&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">例子：&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">class&nbsp;A&nbsp;{&nbsp;...&nbsp;};&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">class&nbsp;B&nbsp;{&nbsp;...&nbsp;};&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">void&nbsp;f()&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">{&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;A*&nbsp;pa&nbsp;=&nbsp;new&nbsp;A;&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;B*&nbsp;pb&nbsp;=&nbsp;new&nbsp;B;&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;void*&nbsp;pv&nbsp;=&nbsp;dynamic_cast&lt;A*&gt;(pa);&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;//&nbsp;pv&nbsp;现在指向了一个类型为A的对象&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;...&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;pv&nbsp;=&nbsp;dynamic_cast&lt;B*&gt;(pb);&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;//&nbsp;pv&nbsp;现在指向了一个类型为B的对象&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">}&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">3）const_cast&lt;T*&gt;(a)&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">去掉类型中的常量，除了const或不稳定的变址数，T和a必须是相同的类型。&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">表达式const_cast&lt;T*&gt;(a)被用于从一个类中去除以下这些属性：const,&nbsp;volatile,&nbsp;和&nbsp;__unaligned。&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">例子：&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">class&nbsp;A&nbsp;{&nbsp;...&nbsp;};&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">void&nbsp;f()&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">{&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;const&nbsp;A&nbsp;*pa&nbsp;=&nbsp;new&nbsp;A;//const对象&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;A&nbsp;*pb;//非const对象&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">//pb&nbsp;=&nbsp;pa;&nbsp;//&nbsp;这里将出错，不能将const对象指针赋值给非const对象&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;pb&nbsp;=&nbsp;const_cast&lt;A*&gt;(pa);&nbsp;//&nbsp;现在OK了&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">...&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">}&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">class&nbsp;A&nbsp;{&nbsp;...&nbsp;};&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">void&nbsp;f()&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">{&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;const&nbsp;A&nbsp;*pa&nbsp;=&nbsp;new&nbsp;A;//const对象&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;A&nbsp;*pb;//非const对象&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">//pb&nbsp;=&nbsp;pa;&nbsp;//&nbsp;这里将出错，不能将const对象指针赋值给非const对象&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;pb&nbsp;=&nbsp;const_cast&lt;A*&gt;(pa);&nbsp;//&nbsp;现在OK了&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">...&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">}&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">class&nbsp;A&nbsp;{&nbsp;...&nbsp;};&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">void&nbsp;f()&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">{&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;const&nbsp;A&nbsp;*pa&nbsp;=&nbsp;new&nbsp;A;//const对象&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;A&nbsp;*pb;//非const对象&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">//pb&nbsp;=&nbsp;pa;&nbsp;//&nbsp;这里将出错，不能将const对象指针赋值给非const对象&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;pb&nbsp;=&nbsp;const_cast&lt;A*&gt;(pa);&nbsp;//&nbsp;现在OK了&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">...&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">}&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">4）reinterpret_cast&lt;T*&gt;(a)&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">任何指针都可以转换成其它类型的指针，T必须是一个指针、引用、算术类型、指向函数的指针或指向一个类成员的指针。&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">表达式reinterpret_cast&lt;T*&gt;(a)能够用于诸如char*&nbsp;到&nbsp;int*，或者One_class*&nbsp;到&nbsp;Unrelated_class*等类似这样的转换，因此可能是不安全的。&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">例子：&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">class&nbsp;A&nbsp;{&nbsp;...&nbsp;};&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">class&nbsp;B&nbsp;{&nbsp;...&nbsp;};&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">void&nbsp;f()&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">{&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;A*&nbsp;pa&nbsp;=&nbsp;new&nbsp;A;&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;void*&nbsp;pv&nbsp;=&nbsp;reinterpret_cast&lt;A*&gt;(pa);&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;//&nbsp;pv&nbsp;现在指向了一个类型为B的对象，这可能是不安全的&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">&nbsp;&nbsp;...&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li class="">}&nbsp; <br></li>
</ol>
</div>
<br><img src ="http://www.cppblog.com/iuranus/aggbug/88257.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2009-06-22 11:24 <a href="http://www.cppblog.com/iuranus/archive/2009/06/22/88257.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>可以根据字符串创建类吗--解决方案 熟练c/c++(六)</title><link>http://www.cppblog.com/iuranus/archive/2009/01/12/71832.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Mon, 12 Jan 2009 14:29:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2009/01/12/71832.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/71832.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2009/01/12/71832.html#Feedback</comments><slash:comments>28</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/71832.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/71832.html</trackback:ping><description><![CDATA[<p>想了很久，结合c++设计新思维的方法，大家这种设计会有什么问题？<br><br><br>－－－－－－－－－－－IShape.h－－－－－－－－－－－－－－－－－<br>class IShape<br>{<br>public:<br>&nbsp;IShape()<br>&nbsp;{<br>&nbsp;&nbsp;printf("\n IShape\n");<br>&nbsp;}<br>&nbsp;virtual ~IShape()<br>&nbsp;{<br>&nbsp;&nbsp;printf("\n ~IShape\n");<br>&nbsp;}<br>&nbsp;virtual void Draw() = 0;<br>};</p>
<p>typedef const char* ShapeType;<br>typedef IShape* (*Creator)();<br><br><br>－－－－－－－－－－－－ShapeFactory.h－－－－－－－－－－－－－－－－－－－－<br><br>class ShapeFactory {<br>public:<br>&nbsp;&nbsp;&nbsp; static ShapeFactory&amp; Instance() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static ShapeFactory instance;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return instance;<br>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; IShape* Create(ShapeType shapeType);<br>&nbsp;&nbsp;&nbsp; bool RegisterShape(ShapeType shapeType, Creator creator);</p>
<p>private:<br>&nbsp;&nbsp;&nbsp; ShapeFactory() {}<br>&nbsp;std::map&lt;ShapeType, Creator&gt; shapeCreators;<br>};<br><br>－－－－－－－－－－－－ShapeFactory.cpp－－－－－－－－－－－－－－－－－－－－<br><br>#include "CFactory.h"</p>
<p>IShape* ShapeFactory::Create(ShapeType shapeType) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creator creator = shapeCreators.find( shapeType )-&gt;second;<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( creator == NULL )&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return NULL;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return creator();<br>}</p>
<p>bool ShapeFactory::RegisterShape( ShapeType shapeType, Creator creator ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map&lt;ShapeType, Creator&gt;::iterator iter;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iter = shapeCreators.find(shapeType);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(iter != shapeCreators.end())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shapeCreators[shapeType] = creator;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}</p>
<p>－－－－－－－－－－－－CCircle .h－－－－－－－－－－－－－－－－－－－－<br>#include&lt;stdio.h&gt;</p>
<p>#include "IShape.h"<br>#include "CFactory.h"<br>class CCircle : public IShape<br>{<br>public:<br>&nbsp;CCircle()<br>&nbsp;{<br>&nbsp;&nbsp;printf("\n CCircle\n");<br>&nbsp;}<br>&nbsp;virtual ~CCircle()<br>&nbsp;{<br>&nbsp;&nbsp;printf("\n ~CCircle\n");<br>&nbsp;}</p>
<p>&nbsp;virtual void Draw();<br>};<br><br><br>－－－－－－－－－－－－CCircle .cpp－－－－－－－－－－－－－－－－－－－－<br>#include "CCircle.h" </p>
<p>IShape* Create() { return new CCircle(); }<br>static const bool RegisterShape__ = ShapeFactory::Instance().RegisterShape( "CCircle", Create);</p>
<p>void CCircle::Draw()<br>{<br>&nbsp;printf("\n CCircle::Draw\n");<br>}<br><br><br>－－－－－－－－－－－－main.cpp－－－－－－－－－－－－－－－－－－－－<br>#include&lt;stdio.h&gt;<br>#include"CFactory.h"</p>
<p>#include "IShape.h"</p>
<p>int main() {<br>&nbsp;&nbsp;&nbsp; IShape* line = ShapeFactory::Instance().Create("CCircle");<br>&nbsp;&nbsp;&nbsp; line-&gt;Draw();&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp; return 0;<br>}<br><br>有点小小的兴奋，大家积极发言哟！！！<br><br>主要参考： <a href="http://blog.csdn.net/jicao/archive/2006/07/01/861343.aspx" target=_new><u><font color=#0000ff>http://blog.csdn.net/jicao/archive/2006/07/01/861343.aspx</font></u></a>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://blog.csdn.net/hjsunj/archive/2008/01/07/2028597.aspx" target=_new><font color=#223355>http://blog.csdn.net/hjsunj/archive/2008/01/07/2028597.aspx</font></a><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;《c++设计新思维》</p>
<img src ="http://www.cppblog.com/iuranus/aggbug/71832.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2009-01-12 22:29 <a href="http://www.cppblog.com/iuranus/archive/2009/01/12/71832.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C语言怎么解析声明 熟练c/c++(五)</title><link>http://www.cppblog.com/iuranus/archive/2009/01/08/71530.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Thu, 08 Jan 2009 13:09:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2009/01/08/71530.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/71530.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2009/01/08/71530.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/71530.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/71530.html</trackback:ping><description><![CDATA[&nbsp;
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>首先声明如果你</span><span>对</span><span>int (*a)[10], char* const (*next());</span><span>已</span><span>经了解，就不要看了，一个声明是没什么意思的，这篇文章只是想阐述下</span><span>C</span><span>语言是怎么解析它的声明</span><span>。</span><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>声明里面可以包括的元素有：</span><span>类型说明符</span><span>(int, void, char,struct...)</span><span>，存</span><span>储类型</span><span>extern, static, register, </span><span>类型限定符</span><span>(const, volatile), </span><span>变量名</span><span>(</span><span>标识符</span><span>), </span><span>符号</span><span>(*</span><span>，</span><span>圆括号和中括号</span><span>)</span><span>；</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>总体原则是，找到标识符</span><span>(</span><span>即是我</span><span>们平时叫的变量名</span><span>)</span><span>，从右向左解析；</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>具体</span><span>步</span><span>骤如下：</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>1. </span><span>找到声明中最左</span><span>边的标识符</span><span>,</span><span>去掉</span><span>标识符</span><span><span>&nbsp;&nbsp; </span>=&gt; </span><span>变量是叫</span><span>&#8220;</span><span>标识符</span><span>&#8221;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>2. </span><span>查看标识符右边的下一个符号</span><span>，</span><span>如果是方括号，取出可能的大小，去掉方括号</span><span> </span><span>＝</span><span>&gt;</span><span>是一个数</span><span>组</span><span>。</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>3. </span><span>查看标识符右边的下一个符号</span><span>，</span></p>
<p><span>&nbsp;</span><span>如果是左</span><span>圆括号，取出可能的参数，一直到右括号</span><span> </span><span>＝</span><span>&gt; </span><span>是一个函数</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>4. </span><span>查看标识符左边的符号</span><span>，</span><span>如果是左括号，找到</span><span>对应的右括号，并把括号中的声明组合在一起</span><span>。回到第</span><span>2</span><span>步重新开始执行。</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>5. </span><span>查看标识符左边的符号</span><span>，</span><span>如果是</span><span>const, volatile,*, </span><span>继续向左读直到不是这三个类型为止</span><span>。</span><span>重复第<span>4</span>步。 </span><span>&nbsp;=&gt;</span><span>解</span><span>释为</span><span>const, volatile,</span><span>指向什</span><span>么的指针</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>6. </span><span>剩下的符号一并</span><span>读入</span><span> =&gt;static unsigned int </span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>你可能想问这几步就可以解决了<span>? </span>是的，这就是所谓的神奇解码环。</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span></span><span>下面我来随便验证下这个算法<span>:</span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>先来个简单的</span></p>
<p><span>int (*a)[10] </span><span>和 <span>int* a[10];</span></span></p>
<p><span>&nbsp;&nbsp; 声明式<span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span>步骤<span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span>执行结果</span></p>
<p><span>int (*a)[10] &nbsp;&nbsp; </span><span>第<span>1</span>步&nbsp;<span><span>&nbsp;&nbsp;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span>找到最左边的标识符<span>a</span>，表示<span>a</span>是一个<span>&#8230;</span></span></p>
<p><span>int (*)[10]<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>第<span>2</span>，<span>3</span>步<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>不匹配</span></p>
<p><span>int (*)[10]<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>第<span>4</span>步<span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span>匹配<span>(,</span>直接读到<span>),</span>包括<span>*</span>，表示<span>a</span>是一个指向<span>&#8230;</span>指针<span>.Step2</span></span></p>
<p><span>int [10]<span>&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>第<span>2</span>步<span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span>匹配<span>[10]</span>，表示<span>a</span>是一个指向<span>..size=10</span>的数组的指针</span></p>
<p><span>int&nbsp;<span>&nbsp;&nbsp;</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>第<span>3</span>，<span>4</span>，<span>5&nbsp;&nbsp;&nbsp;&nbsp;</span>不匹配</span></p>
<p><span>结束<span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span>第<span>6</span>步<span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span>表示<span>a</span>是一个指向<span>int</span>数组的指针</span></p>
<p><span>int* a[10]&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span>第<span>1</span>步<span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>a</span>是一个</span></p>
<p><span>int* [10]<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>第<span>2</span>步<span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>a</span>是一个<span>&#8230;size=10</span>的数组</span></p>
<p><span>int*<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span>第<span>3</span>步<span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span>不匹配</span></p>
<p><span>int<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>第<span>4</span>步<span><span>&nbsp;&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>匹配，<span>a</span>是一个存放着指针，<span>size=10</span>的数组</span></p>
<p><span>int<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span>第<span>5</span>步<span><span>&nbsp;&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>匹配，<span>a</span>是一个存放着<span>int</span>指针，<span>size=10</span>的数组</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>大家</span><span>看</span><span>的出两个声明的结果是一个是指针，一个是数组。</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>int a1[10];</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>int a2[20];<span> </span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>int (*b)[10];</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>int* c[10];</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>a[0] = 10;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>b = &amp;a2;<span>&nbsp;&nbsp;&nbsp; </span>//</span><span>报错，</span><span>cannot convert from 'int (*)[20]' to 'int (*)[10]'</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>b = &amp;a1;<span>&nbsp;&nbsp;&nbsp; </span>//b</span><span>是指向</span><span>size=10</span><span>的数组的指针</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>c[0] = &amp;a1[0];&nbsp;//c</span><span>是一个数组，里面存放的是指针，指针指向</span><span>int;</span></p>
<br>（未完待续） 
<img src ="http://www.cppblog.com/iuranus/aggbug/71530.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2009-01-08 21:09 <a href="http://www.cppblog.com/iuranus/archive/2009/01/08/71530.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>结构体对齐那点事 熟练c/c++(四) </title><link>http://www.cppblog.com/iuranus/archive/2009/01/06/71388.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Tue, 06 Jan 2009 15:39:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2009/01/06/71388.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/71388.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2009/01/06/71388.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/71388.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/71388.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>刚刚完成一个文件的迁移程序，其中遇到了结构体对齐的问题，所以拿出来说说，与各位博友们分享。</span></p>
<p><span>我的程序很简单，就是把之前通过一个结构体</span><span>fwrite</span><span>到文件</span><span>A</span><span>里的内容读出，然后转给另一个结构体保存。程序是简单，但我担心的是之前<strong>把</strong>结构体</span><span>fwrite</span><span>到文件</span><span>A</span><span>的程序对齐结构体规则是怎样的？一定要知道它吗</span><span>? </span><span>当然了，如果那个程序结构体是按照</span><span>1</span><span>对齐写入的，我的程序结构体是按照</span><span>4</span><span>对齐读入，那不就糟了！</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>这里我引入结构体对齐的概念，也可以说是内存对齐了。为什么要内存对齐呢，就是方便</span><span>CPU</span><span>寻址了，具体原因大家要参考计算机体系结构了。先看一个内存对齐的例子：</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>struct example1{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>char a;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>double b;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>long l;</span></p>
<p><span>};</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>struct example2{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>char a;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>long l;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>double b;</span></p>
<p><span>};</span></p>
<p><span>大家算算结构体大小，初次接触的博友可能对答案有点惊讶，</span><span>VC</span><span>编译，</span><span> sizeof</span><span>后结果分别是：</span><span>24</span><span>，</span><span>16</span><span>。</span><span> </span><span>同样是的结构体，成员换了顺序，大小就不同了。其实内存对齐有个规则，只要知道了，就</span><span>OK</span><span>。那么以下</span><span>5</span><span>点是关键</span></p>
<p><span><span>1．<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>内存对齐与编译器设置有关，首先要搞清编译器这个默认值是多少</span></p>
<p><span><span>2．<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>如果不想编译器默认的话，可以通过</span><span>#pragma pack(n)</span><span>来指定按照</span><span>n</span><span>对齐</span></p>
<p><span><span>3．<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>每个结构体变量对齐，如果对齐参数</span><span>n(</span><span>编译器默认或者通过</span><span>pragma</span><span>指定</span><span>)</span><span>大于该变量所占字节数</span><span>(m)</span><span>，那么就按照</span><span>m</span><span>对齐，内存偏移后的地址是</span><span>m</span><span>的倍数，否则是按照</span><span>n</span><span>对齐，内存偏移后的地址是</span><span>n</span><span>的倍数。也就是最小化长度规则</span></p>
<p><span><span>4．<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>结构体总大小</span><span>: </span><span>对齐后的长度必须是成员中最大的对齐参数的整数倍。最大对齐参数是从第三步得到的。</span></p>
<p><span><span>5．<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>补充：如果结构体</span><span>A</span><span>中还要结构体</span><span>B</span><span>，那么</span><span>B</span><span>的对齐方式是选它里面最长的成员的对齐方式</span></p>
<p><span>所以计算结构体大小要走三步，首先确定是当前程序按照几对齐</span><span>(</span><span>参照</span><span>1</span><span>，</span><span>2</span><span>点</span><span>)</span><span>，接着计算每个结构体变量的大小和偏移</span><span>(</span><span>参照</span><span>3</span><span>，</span><span>5)</span><span>，最后计算结构体总大小（参照</span><span>4</span><span>）。</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>先算算</span><span>example1</span><span>吧，假设编译器是以</span><span>16</span><span>对齐的</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>1</span><span>．确定按照几对齐</span><span>: 16;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>2</span><span>．确定每个成员的偏移：</span><span>a </span><span>占一个字节，</span><span>16&gt;1, </span><span>按照</span><span>1</span><span>对齐，起始位置</span><span>0</span><span>，</span><span>0%1 = 0</span><span>，那么</span><span>a</span><span>就存在</span><span>0</span><span>位置；</span><span>b</span><span>占</span><span>8</span><span>个字节，</span><span>16&gt;8</span><span>，按照</span><span>8</span><span>对齐，起始位置就不能是</span><span>1</span><span>了，因为要按照</span><span>8</span><span>对齐，所以最近的偏移起始位置是</span><span>8</span><span>，</span><span> 8%8 =0, </span><span>那么</span><span>b</span><span>就存在位置</span><span>8-15</span><span>的位置；</span><span>l</span><span>占</span><span>4</span><span>个字节，</span><span>16&gt;4</span><span>，按照</span><span>4</span><span>对齐，起始位置</span><span>16</span><span>，</span><span> 16%4=0</span><span>，那么</span><span>l</span><span>就存在位置</span><span>16-19</span><span>的位置。所以结构体从</span><span>0</span><span>到</span><span>19</span><span>一共占用</span><span>20</span><span>个字节</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>3</span><span>．结构体总大小：成员中最大的对齐参数是</span><span>b</span><span>的</span><span>8</span><span>对齐，所以</span><span>20</span><span>％</span><span>8!=0, 24</span><span>刚好。</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>真的很搞！同理计算</span><span>example2</span><span>应该是</span><span>16</span><span>；</span></p>
<p><span>&nbsp;<span>&nbsp;&nbsp;&nbsp; </span></span><span>再举个结构体嵌套的例子吧，</span></p>
<p><span>#pragma pack(push)</span></p>
<p><span>#pragma pack(8)</span></p>
<p><span>struct test1{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>int a;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>char b;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>int c[20]</span></p>
<p><span>long l;</span></p>
<p><span>} ;</span></p>
<p><span>struct test2{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>char a1;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>char a2;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>struct test1 t1;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>double b1;</span></p>
<p><span>}</span></p>
<p><span>#pragma pack(pop)</span></p>
<p><span>先计算</span><span>test1, 8</span><span>对齐，</span><span>a</span><span>占用</span><span>0-3</span><span>，</span><span>b</span><span>占用</span><span>4</span><span>，</span><span>c</span><span>占用</span><span>8</span><span>－</span><span>87</span><span>，</span><span>l</span><span>占用</span><span>88</span><span>－</span><span>91</span><span>，一共</span><span>92</span><span>个字节。成员中最大的对齐参数是</span><span>int</span><span>了</span><span>92%4=0;</span></p>
<p><span>再计算</span><span>test2, a1z</span><span>占用</span><span>0</span><span>，</span><span>a2</span><span>占用</span><span>1</span><span>，</span><span>t1</span><span>呢，4 % 4 (test1里面最长的成员的对齐方式) </span><span>= 0, 4-95</span><span>，</span><span>b1</span><span>占</span><span>96</span><span>到</span><span>103</span><span>；一共</span><span>104</span><span>个字节，成员中最大的对齐参数是</span><span>double</span><span>了</span><span>104%8=0; </span><span>所以是</span><span>104.</span><br></p>
<p><span><span><br>&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;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;挤时间写的，</span></span><span>有的地方有遗漏，请各位指正！</span></p>
<img src ="http://www.cppblog.com/iuranus/aggbug/71388.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2009-01-06 23:39 <a href="http://www.cppblog.com/iuranus/archive/2009/01/06/71388.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>public继承后，父类与子类访问隐藏 熟练c/c++(三)</title><link>http://www.cppblog.com/iuranus/archive/2009/01/05/71210.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Mon, 05 Jan 2009 03:16:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2009/01/05/71210.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/71210.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2009/01/05/71210.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/71210.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/71210.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;《Effective C++》的第六章节继承与面向对象设计花了大部分的篇幅在介绍继承遮掩(Hiding Inherited Name)，那我也效仿下大师，做个小的总结。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public继承的目的是要建立父子类的is-a关系，也就是说用到父类的地方，在子类一定能用。现实的代码编写中，我们主要也是用public继承，所以每个人都有自己一套继承的写法和调用，直到看到Effecitve C++时，才会发现还有很多其它的用法，在这里我并不鼓励大家尝试各种写法，毕竟代码要稳定，我只是想把一些可能的形式表现出来，供大家参考。<br>class Base<br>{<br>&nbsp;public:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual void fn() = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual void fn(int i){printf("\n Base: fn(int)\n");};<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual void fn2() {printf("\n Base: void fn2(int)\n");}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void fn3() {printf("\n Base: fn3()\n");}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void fn4(){printf("\n Base: fn4()\n");}<br>};<br><br>class ClassA : public Base<br>{<br>public:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ClassA(int n, int d);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;using Base::fn2;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual void fn(){printf("\n ClassA: fn()\n");};<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual void fn(int i){printf("\n ClassA: fn(INT)\n");};<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual void fn2(int i) {printf("\n ClassA: fn2(INT)\n"); }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void fn3() {printf("\n ClassA: fn3()\n");}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void fn4(int i){printf("\n ClassA: fn4()\n");}<br>&nbsp;};<br>int main()<br>{&nbsp;<br>Base* pBase1 = new ClassA(10, 20);<br>&nbsp;pBase1-&gt;fn();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //OK，ClassA: fn()<br>&nbsp;pBase1-&gt;fn(11);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //OK，ClassA: fn(INT)<br>&nbsp;pBase1-&gt;fn2();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//OK，Base: void fn2(int)<br>&nbsp;pBase1-&gt;fn2(2);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //NO, 不能访问<br>&nbsp;pBase1-&gt;fn3();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//OK，Base: fn3()<br>&nbsp;pBase1-&gt;fn4();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//OK，Base: fn4()<br>&nbsp;pBase1-&gt;fn4(2);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //NO，不能访问<br>&nbsp;printf("\n============================================\n");<br>&nbsp;ClassA* pDerived = new ClassA(10, 20);<br>&nbsp;pDerived-&gt;fn();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//OK，ClassA: fn()<br>&nbsp;pDerived-&gt;fn(1);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //OK，ClassA: fn(INT)<br>&nbsp;pDerived-&gt;fn2();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //NO，不能访问<br>&nbsp;pDerived-&gt;fn2(2);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //OK，ClassA: fn2(INT)<br>&nbsp;pDerived-&gt;fn3();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //OK，ClassA: fn3()<br>&nbsp;pDerived-&gt;fn4();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //NO，不能访问<br>&nbsp;pDerived-&gt;fn4(2);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //NO，ClassA: fn4(INT)<br>&nbsp;printf("\n============================================\n");<br>&nbsp;return 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>}</p>
<p><br>子类父类同名virtual函数(参数相同)， 用子类的指针，引用，对象访问时，子类会覆盖父类方法(只能访问子类方法)。<br>子类父类同名virtual函数(参数相同)， 用父类的指针，引用，对象访问时，子类会覆盖父类方法(只能访问子类方法)。<br>子类父类同名virtual函数(参数不同)， 用子类的指针，引用，对象访问时，子类会覆盖父类方法(只能访问子类方法)。<br>子类父类同名virtual函数(参数不同)， 用父类的指针，引用，对象访问时，父类会覆盖子类方法(只能访问父类方法)。<br>子类父类同名virtual函数(函数类型不同const/non-const)， 用子类的指针，引用，对象访问时，子类会覆盖父类方法(只能访问子类方法)。<br>子类父类同名virtual函数(函数类型不同const/non-const)， 用父类的指针，引用，对象访问时，父类会覆盖子类方法(只能访问父类方法)。</p>
<p>结论：参数和函数类型是c++编译器判断要不要多态的关键因素。注: 返回类型不同时，编译器会报错，virtual不能和static连用。静态成员函数，没有隐藏的this指针，virtual函数一定要通过对象来调用，既要this指针。<br>改进:：如果子类指针想访问到父类，可以在子类里加入:using 父类名::函数名；如pDerived-&gt;fn2();&nbsp;访问父类方法，在ClassA里面加入using Base::fn2，就可以访问了。如果父类指针想访问到子类，就需要指针转换了。<br><br>子类父类同名non-virtual函数(无论参数/返回/函数类型(const或static))，用子类的指针，引用，对象访问，子类会覆盖父类方法(只能访问子类方法)。<br>子类父类同名non-virtual函数(无论参数/返回/函数类型(const或static))，用父类的指针，引用，对象访问，父类会覆盖子类方法(只能访问父类方法)。<br><br>结论: non-virtual函数，既没有任何多态效果，如果父类要访问子类，只用指针转换。&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;所谓大道至简，想必大家看着这个都烦，我也是。想了想应该这样表达最简单：<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;子类public继承父类的函数，唯有满足(参数，返回值，函数类型相同&amp;父类是virtual)函数，父类的指针，引用(也指针实现的)能够多态的访问子类，否则父类指针只能访问父类的方法。&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;子类public继承父类的函数，子类的方法名会遮掩父类的相同名的方法。子类要想访问父类的方法，使用using 父类名::函数名。&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;具体的原因我觉得可能还是得找时间拜读下候杰译的《C++对象模型》，看看到底这个东西是怎么设计的。<br></p>
<img src ="http://www.cppblog.com/iuranus/aggbug/71210.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2009-01-05 11:16 <a href="http://www.cppblog.com/iuranus/archive/2009/01/05/71210.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>（转载）图文例解C++类的多重继承与虚拟继承</title><link>http://www.cppblog.com/iuranus/archive/2008/12/18/69722.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Thu, 18 Dec 2008 03:15:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2008/12/18/69722.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/69722.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2008/12/18/69722.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/69722.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/69722.html</trackback:ping><description><![CDATA[在过去的学习中，我们始终接触的单个类的继承，但是在现实生活中，一些新事物往往会拥有两个或者两个以上事物的属性，为了解决这个问题，C++引入了多重继承的概念，<font color=#ff0000><strong>C++允许为一个派生类指定多个基类，这样的继承结构被称做多重继承</strong></font>。
<p>　　举个例子，交通工具类可以派生出汽车和船两个子类，但拥有汽车和船共同特性水陆两用汽车就必须继承来自汽车类与船类的共同属性。 <br><br>　　由此我们不难想出如下的图例与代码：</p>
<p align=center><img alt="" src="http://www.pconline.com.cn/pcedu/empolder/gj/c/0503/pic/21cppc01.gif" border=0></p>
<p>　<font style="BACKGROUND-COLOR: #b000b0" color=#ffffff>当一个派生类要使用多重继承的时候，必须在派生类名和冒号之后列出所有基类的类名，并用逗好分隔。</font> </p>
<p class=code clear=both><font color=green>&nbsp;&nbsp;</font>&nbsp;<br>&nbsp; <br>#include&nbsp;&lt;<font color=maroon>iostream</font>&gt;&nbsp; <br><font color=blue>using</font>&nbsp;<font color=blue>namespace</font>&nbsp;std;&nbsp; <br>&nbsp; <br><font color=blue>class</font>&nbsp;Vehicle&nbsp; <br>{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>public</font>:&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Vehicle(<font color=blue>int</font>&nbsp;weight&nbsp;<font color=red>=</font>&nbsp;0)&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Vehicle::weight&nbsp;<font color=red>=</font>&nbsp;weight;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>void</font>&nbsp;SetWeight(<font color=blue>int</font>&nbsp;weight)&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=maroon>cout</font>&lt;&lt;"重新设置重量"&lt;&lt;endl;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Vehicle::weight&nbsp;<font color=red>=</font>&nbsp;weight;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>virtual</font>&nbsp;<font color=blue>void</font>&nbsp;ShowMe()&nbsp;<font color=red>=</font>&nbsp;0;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>protected</font>:&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>int</font>&nbsp;weight;&nbsp; <br>};&nbsp; <br><font color=blue>class</font>&nbsp;Car:<font color=blue>public</font>&nbsp;Vehicle<font color=green>//汽车&nbsp;</font> <br>{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>public</font>:&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Car(<font color=blue>int</font>&nbsp;weight=0,<font color=blue>int</font>&nbsp;aird=0):Vehicle(weight)&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Car::aird&nbsp;<font color=red>=</font>&nbsp;aird;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>void</font>&nbsp;ShowMe()&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=maroon>cout</font>&lt;&lt;"我是汽车！"&lt;&lt;endl;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>protected</font>:&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>int</font>&nbsp;aird;&nbsp; <br>};&nbsp; <br>&nbsp; <br><font color=blue>class</font>&nbsp;Boat:<font color=blue>public</font>&nbsp;Vehicle<font color=green>//船&nbsp;</font> <br>{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>public</font>:&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Boat(<font color=blue>int</font>&nbsp;weight=0,<font color=blue>float</font>&nbsp;tonnage=0):Vehicle(weight)&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Boat::tonnage&nbsp;<font color=red>=</font>&nbsp;tonnage;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>void</font>&nbsp;ShowMe()&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=maroon>cout</font>&lt;&lt;"我是船！"&lt;&lt;endl;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>protected</font>:&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>float</font>&nbsp;tonnage;&nbsp; <br>};&nbsp; <br>&nbsp; <br><font color=blue>class</font>&nbsp;AmphibianCar:<font color=blue>public</font>&nbsp;Car,<font color=blue>public</font>&nbsp;Boat<font color=green>//水陆两用汽车,多重继承的体现&nbsp;</font> <br>{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>public</font>:&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AmphibianCar(<font color=blue>int</font>&nbsp;weight,<font color=blue>int</font>&nbsp;aird,<font color=blue>float</font>&nbsp;tonnage)&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:Vehicle(weight),Car(weight,aird),Boat(weight,tonnage)&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=green>//多重继承要注意调用基类构造函数&nbsp;</font> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>void</font>&nbsp;ShowMe()&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=maroon>cout</font>&lt;&lt;"我是水陆两用汽车！"&lt;&lt;endl;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; <br>};&nbsp; <br><font color=blue>int</font>&nbsp;<font color=blue>main</font>()&nbsp; <br>{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;AmphibianCar&nbsp;a(4,200,1.35f);<font color=green>//错误&nbsp;</font> <br>&nbsp;&nbsp;&nbsp;&nbsp;a.SetWeight(3);<font color=green>//错误&nbsp;</font> <br>&nbsp;&nbsp;&nbsp;&nbsp;system("pause");&nbsp;&nbsp; <br>}</p>
<p>　　上面的代码从表面看，看不出有明显的语发错误，但是它是不能够通过编译的。这有是为什么呢？ <br>　　这是由于多重继承带来的<font color=#ff0000><font color=#ff0000>继承的模糊性</font></font>带来的问题。</p>
<p>&nbsp;　先看如下的图示： </p>
<p>&nbsp;</p>
<p align=center><img alt="" src="http://www.pconline.com.cn/pcedu/empolder/gj/c/0503/pic/21cppc02.gif" border=0></p>
<p>　　在图中深红色标记出来的地方正是主要问题所在，水陆两用汽车类继承了来自Car类与Boat类的属性与方法，Car类与Boat类同为AmphibianCar类的基类，在内存分配上AmphibianCar获得了来自两个类的SetWeight()成员函数，当我们调用a.SetWeight(3)的时候计算机不知道如何选择分别属于两个基类的被重复拥有了的类成员函数SetWeight()。 </p>
<p>　　由于这种模糊问题的存在同样也导致了AmphibianCar a(4,200,1.35f);执行失败，系统会产生Vehicle&#8221;不是基或成员的错误。</p>
<p>　　以上面的代码为例，我们要想让AmphibianCar类既获得一个Vehicle的拷贝，而且又同时共享用Car类与Boat类的数据成员与成员函数就必须通过C++所提供的<font color=#ff0000><strong>虚拟继承</strong></font>技术来实现。</p>
<p>　　我们在Car类和Boat类继承Vehicle类出，在前面加上virtual关键字就可以实现虚拟继承，使用虚拟继承后，<font style="BACKGROUND-COLOR: #b000b0" color=#ffffff>当系统碰到多重继承的时候就会自动先加入一个Vehicle的拷贝，当再次请求一个Vehicle的拷贝的时候就会被忽略，保证继承类成员函数的唯一性</font>。 <br><br>　　修改后的代码如下，注意观察变化：</p>
<p class=code><br>#include&nbsp;&lt;<font color=maroon>iostream</font>&gt;&nbsp; <br><font color=blue>using</font>&nbsp;<font color=blue>namespace</font>&nbsp;std;&nbsp; <br>&nbsp; <br><font color=blue>class</font>&nbsp;Vehicle&nbsp; <br>{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>public</font>:&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Vehicle(<font color=blue>int</font>&nbsp;weight&nbsp;<font color=red>=</font>&nbsp;0)&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Vehicle::weight&nbsp;<font color=red>=</font>&nbsp;weight;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=maroon>cout</font>&lt;&lt;"载入Vehicle类构造函数"&lt;&lt;endl;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>void</font>&nbsp;SetWeight(<font color=blue>int</font>&nbsp;weight)&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=maroon>cout</font>&lt;&lt;"重新设置重量"&lt;&lt;endl;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Vehicle::weight&nbsp;<font color=red>=</font>&nbsp;weight;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>virtual</font>&nbsp;<font color=blue>void</font>&nbsp;ShowMe()&nbsp;<font color=red>=</font>&nbsp;0;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>protected</font>:&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>int</font>&nbsp;weight;&nbsp; <br>};&nbsp; <br><font color=blue>class</font>&nbsp;Car:<font color=blue>virtual</font>&nbsp;<font color=blue>public</font>&nbsp;Vehicle<font color=green>//汽车，这里是虚拟继承&nbsp;</font> <br>{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>public</font>:&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Car(<font color=blue>int</font>&nbsp;weight=0,<font color=blue>int</font>&nbsp;aird=0):Vehicle(weight)&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Car::aird&nbsp;<font color=red>=</font>&nbsp;aird;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=maroon>cout</font>&lt;&lt;"载入Car类构造函数"&lt;&lt;endl;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>void</font>&nbsp;ShowMe()&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=maroon>cout</font>&lt;&lt;"我是汽车！"&lt;&lt;endl;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>protected</font>:&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>int</font>&nbsp;aird;&nbsp; <br>};&nbsp; <br>&nbsp; <br><font color=blue>class</font>&nbsp;Boat:<font color=blue>virtual</font>&nbsp;<font color=blue>public</font>&nbsp;Vehicle<font color=green>//船,这里是虚拟继承&nbsp;</font> <br>{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>public</font>:&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Boat(<font color=blue>int</font>&nbsp;weight=0,<font color=blue>float</font>&nbsp;tonnage=0):Vehicle(weight)&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Boat::tonnage&nbsp;<font color=red>=</font>&nbsp;tonnage;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=maroon>cout</font>&lt;&lt;"载入Boat类构造函数"&lt;&lt;endl;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>void</font>&nbsp;ShowMe()&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=maroon>cout</font>&lt;&lt;"我是船！"&lt;&lt;endl;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>protected</font>:&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>float</font>&nbsp;tonnage;&nbsp; <br>};&nbsp; <br>&nbsp; <br><font color=blue>class</font>&nbsp;AmphibianCar:<font color=blue>public</font>&nbsp;Car,<font color=blue>public</font>&nbsp;Boat<font color=green>//水陆两用汽车,多重继承的体现&nbsp;</font> <br>{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>public</font>:&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AmphibianCar(<font color=blue>int</font>&nbsp;weight,<font color=blue>int</font>&nbsp;aird,<font color=blue>float</font>&nbsp;tonnage)&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:Vehicle(weight),Car(weight,aird),Boat(weight,tonnage)&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=green>//多重继承要注意调用基类构造函数&nbsp;</font> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=maroon>cout</font>&lt;&lt;"载入AmphibianCar类构造函数"&lt;&lt;endl;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>void</font>&nbsp;ShowMe()&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=maroon>cout</font>&lt;&lt;"我是水陆两用汽车！"&lt;&lt;endl;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=blue>void</font>&nbsp;ShowMembers()&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color=maroon>cout</font>&lt;&lt;"重量："&lt;&lt;weight&lt;&lt;"顿，"&lt;&lt;"空气排量："&lt;&lt;aird&lt;&lt;"CC，"&lt;&lt;"排水量："&lt;&lt;tonnage&lt;&lt;"顿"&lt;&lt;endl;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; <br>};&nbsp; <br><font color=blue>int</font>&nbsp;<font color=blue>main</font>()&nbsp; <br>{&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;AmphibianCar&nbsp;a(4,200,1.35f);&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;a.ShowMe();&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;a.ShowMembers();&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;a.SetWeight(3);&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;a.ShowMembers();&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;system("pause");&nbsp;&nbsp; <br>}</p>
<p>　　注意观察类构造函数的构造顺序。 <br><br><strong>　　虽然说虚拟继承与虚函数有一定相似的地方，但读者务必要记住，他们之间是绝对没有任何联系的！</strong></p>
<img src ="http://www.cppblog.com/iuranus/aggbug/69722.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2008-12-18 11:15 <a href="http://www.cppblog.com/iuranus/archive/2008/12/18/69722.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++怎么实现AOP</title><link>http://www.cppblog.com/iuranus/archive/2007/12/14/38507.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Fri, 14 Dec 2007 06:02:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2007/12/14/38507.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/38507.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2007/12/14/38507.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/38507.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/38507.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AOP技术的诞生并不算晚，早在1990年开始，来自Xerox Palo Alto Research Lab（即PARC）的研究人员就对面向对象思想的局限性进行了分析。他们研究出了一种新的编程思想，借助这一思想或许可以通过减少代码重复模块从而帮助开发人员提高工作效率。随着研究的逐渐深入，AOP也逐渐发展成一套完整的程序设计思想，各种应用AOP的技术也应运而生。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AOP技术在Java平台下是最先得到应用的。就在PARC对于面向方面编程进行研究的同时，美国Northeastern University的博士生Cristina Lopes和其同事也开始了类似的思考。最终，美国国防先进技术研究计划署（Defense Advanced Research Projects Agency即DARPA）注意到了这项工作，并提供了科研经费，鼓励将二者的工作成果结合起来。他们通过定义一套Java语言的扩展系统，使开发者可以方便的进行面向方面的开发，这套扩展系统被称为AspectJ。之后，AspectJ在2002年被转让给Eclipse Foundation，从而成为在开源社区中AOP技术的先锋，也是目前最为流行的AOP工具。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;那么对于C++技术来说，怎样来开展AOP呢，幸好<strong>有Olaf Spinczyk</strong> 这样的人存在，我们也有了aspect c++。它使用了插入代码的方法。一个典型的Aspect C++示例需要一个C++源文件(.cpp)、一个aspect C++源文件(.ah)，通过ac++编译器把C++源文件和aspect C++源文件转换成混合的C++源文件(如果有头文件也会转换)，最后通过普通的C++编译器编译出可执行文件。<br>&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 那么我现在如果不想用第三方编译器，自己去实现AOP，不知道CPPBLOG里的大虾有什么想法？<br></p>
<img src ="http://www.cppblog.com/iuranus/aggbug/38507.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2007-12-14 14:02 <a href="http://www.cppblog.com/iuranus/archive/2007/12/14/38507.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>小谈const  熟练C/C++（二）</title><link>http://www.cppblog.com/iuranus/archive/2007/10/11/33967.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Thu, 11 Oct 2007 13:09:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2007/10/11/33967.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/33967.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2007/10/11/33967.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/33967.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/33967.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要:    const关键字可以说是用途广泛，从对变量的限定到对函数的限定，尤其是那个指向常量的指针（const int *p），指针常量(int * const p)，指向常量的指针常量(const  int* const p)更让初学者摸不到头脑。这里我主要想描述下最近项目中关于const的一个问题。其实有的时候还不能被表面现象迷惑了，简单代码如下&nbsp;&nbsp;<a href='http://www.cppblog.com/iuranus/archive/2007/10/11/33967.html'>阅读全文</a><img src ="http://www.cppblog.com/iuranus/aggbug/33967.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2007-10-11 21:09 <a href="http://www.cppblog.com/iuranus/archive/2007/10/11/33967.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>返回内部静态成员  熟练C/C++（一）  </title><link>http://www.cppblog.com/iuranus/archive/2007/04/13/21798.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Fri, 13 Apr 2007 08:07:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2007/04/13/21798.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/21798.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2007/04/13/21798.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/21798.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/21798.html</trackback:ping><description><![CDATA[&nbsp;
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 看完陈皓的</span><span>C/C++</span><span>返回内部静态成员的陷阱，认识到自己确实对</span><span>C/C++</span><span>本身语法研究的不够清楚，所以这些时间就在对基本知识进行回顾，真的还蛮有意思的。</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我在用</span><span>C/C++</span><span>函数时，从没有全面考虑过该函数功能，只是知道它能做，基本对函数细节没有了解，就拿下面这个函数做个例子：</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char *inet_ntoa(struct in_addr in);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct in_addr {<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>unsigned long int s_addr; }</span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 看到这个我就能想到该函数是把一个</span><span>unsigned long type</span><span>的数转换成一个字符串。其它什么都不想。现在让我们来仔细品读里面的东西。</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我传入一个</span><span>unsigned long type</span><span>的数据，它给我传出一个</span><span>char *</span><span>，那这个</span><span>char * </span><span>在函数里怎么分配空间的。首先不可能是堆分配，因为如果是那样的话，你用完这个函数后还要释放资源。其次不可能是栈分配，因为那样函数返回后栈也会跟着释放。那还有可能是全局变量，如果这样的话，</span><span>C/C++</span><span>中已经有好多全局了。那还有一种是</span><span>static</span><span>的可能，</span><span>static</span><span>不会随着函数的返回而释放，也就是说，它是一块长期被分配的内存空间，现在在假若我在程序中这样写：</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;%s, %s&#8221;, inet_ntoa(a), inet_ntoa(b));&nbsp;//a, b </span><span>是两个不相等的值</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>输出会让我大吃一惊，输出结果一样。原因很简单，就是</span><span>printf</span><span>先求</span><span>b</span><span>，把值给了那个</span><span>static</span><span>，然后再求</span><span>a, </span><span>把值又给了</span><span>static</span><span>，</span><span>static</span><span>的那块内存最终被写入了</span><span>a</span><span>的值，这个时候输出，那当然就输出的同一个值了。还有一种错误写法，如下：</span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Char *tmp1 = inet_ntoa(a);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Char *tmp2 = inet_ntoa(b);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>这样也是有问题的，因为</span><span>tmp1</span><span>和</span><span>tmp2</span><span>都指向了一块内存，当前的</span><span>static</span><span>的值就是</span><span>b</span><span>的值了。所以总结如下，使用这种函数一定要</span><span>copy</span><span>函数返回的值，而不能去保存其内存地址！<br>附inet_ntoa()源码：<br>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>#include &lt;arpa/inet.h&gt;<br>#include &lt;bits/libc-lock.h&gt;<br><br><span class=cc><font color=#006600>/* The interface of this function is completely stupid, it requires a<br>&nbsp;&nbsp; static buffer.&nbsp; We relax this a bit in that we allow at least one<br>&nbsp;&nbsp; buffer for each thread.&nbsp; */</font></span><br><br><span class=cc><font color=#006600>/* This is the key for the thread specific memory.&nbsp; */</font></span><br>static __libc_key_t key;<br><br><span class=cc><font color=#006600>/* If nonzero the key allocation failed and we should better use a<br>&nbsp;&nbsp; static buffer than fail.&nbsp; */</font></span><br>static char local_buf[18];<br><span style="COLOR: red">static char *static_buf;&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; //静态</span><br><br><span class=cc><font color=#006600>/* Destructor for the thread-specific data.&nbsp; */</font></span><br><a name=a0></a>static void init (void);<br>static void free_key_mem (void *mem);<br><br><br>char *<br><strong class=cchl id=m0><font style="BACKGROUND-COLOR: #aaffff">inet_ntoa</font></strong> (struct in_addr in)<br>{<br>&nbsp; __libc_once_define (static, once);<br>&nbsp; char *buffer;<br>&nbsp; unsigned char *bytes;<br><br>&nbsp; <span class=cc><font color=#006600>/* If we have not yet initialized the buffer do it now.&nbsp; */</font></span><br>&nbsp; __libc_once (once, init);<br><br>&nbsp; if (static_buf != NULL)<br>&nbsp;&nbsp;&nbsp; buffer = static_buf;<br>&nbsp; else<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class=cc><font color=#006600>/* We don't use the static buffer and so we have a key.&nbsp; Use it<br>to get the thread-specific buffer.&nbsp; */</font></span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer = __libc_getspecific (key);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (buffer == NULL)<br>{<br>&nbsp; <span class=cc><font color=#006600>/* No buffer allocated so far.&nbsp; */</font></span><br>&nbsp; buffer = malloc (18);<br>&nbsp; if (buffer == NULL)<br>&nbsp;&nbsp;&nbsp; <span class=cc><font color=#006600>/* No more memory available.&nbsp; We use the static buffer.&nbsp; */</font></span><br>&nbsp;&nbsp;&nbsp; buffer = local_buf;<br>&nbsp; else<br>&nbsp;&nbsp;&nbsp; __libc_setspecific (key, buffer);<br>}<br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp; bytes = (unsigned char *) &amp;in;<br>&nbsp; __snprintf (buffer, 18, "%d.%d.%d.%d",<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bytes[0], bytes[1], bytes[2], bytes[3]);<br><br>&nbsp; return buffer;<br>}<br><br><br><span class=cc><font color=#006600>/* Initialize buffer.&nbsp; */</font></span><br>static void<br>init (void)<br>{<br>&nbsp; if (__libc_key_create (&amp;key, free_key_mem))<br>&nbsp;&nbsp;&nbsp; <span class=cc><font color=#006600>/* Creating the key failed.&nbsp; This means something really went<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wrong.&nbsp; In any case use a static buffer which is better than<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nothing.&nbsp; */</font></span><br>&nbsp;&nbsp;&nbsp; static_buf = local_buf;<br>}<br></span></p>
<img src ="http://www.cppblog.com/iuranus/aggbug/21798.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2007-04-13 16:07 <a href="http://www.cppblog.com/iuranus/archive/2007/04/13/21798.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>心情不错</title><link>http://www.cppblog.com/iuranus/archive/2007/03/28/20799.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Wed, 28 Mar 2007 11:52:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2007/03/28/20799.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/20799.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2007/03/28/20799.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/20799.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/20799.html</trackback:ping><description><![CDATA[<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">经过一些时候项目中对</span> <span lang=EN-US>C++</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的使用，我算是有一个</span> <span lang=EN-US>C++</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的项目经验，但是反过来说，我只是写些基本的程序，没有深入到构架，主要还是用</span> <span lang=EN-US>C</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的思想，昨天写</span> <span lang=EN-US>struct</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时，我发现在</span> <span lang=EN-US>C</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span> <span lang=EN-US>C++</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中写法是不是样的。</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>C</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：</span> <span lang=EN-US></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-spacerun: yes">&nbsp; </span>struct Node{<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">声明</span> <span lang=EN-US><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>int node;</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>struct Node *next;<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">定义</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-spacerun: yes">&nbsp; </span>};</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-spacerun: yes">&nbsp; </span>struct Node list;</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-spacerun: yes">&nbsp; </span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或者</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-spacerun: yes">&nbsp; </span>typedef<span style="mso-spacerun: yes">&nbsp; </span>Node {<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10.5pt; mso-char-indent-count: 1.0"><span lang=EN-US><span style="mso-spacerun: yes">&nbsp;&nbsp; </span>int node;</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10.5pt; mso-char-indent-count: 1.0"><span lang=EN-US><span style="mso-spacerun: yes">&nbsp;&nbsp; </span>struct Node *next; </span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10.5pt; mso-char-indent-count: 1.0"><span lang=EN-US>}ListLink;</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-spacerun: yes">&nbsp; </span>ListLink list;</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><o:p>&nbsp;</o:p> </span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US>C++:</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-spacerun: yes">&nbsp; </span>struct Node{</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10.5pt; mso-char-indent-count: 1.0"><span lang=EN-US><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>Int node;</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10.5pt; mso-char-indent-count: 1.0"><span lang=EN-US><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>Node *next;</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10.5pt; mso-char-indent-count: 1.0"><span lang=EN-US>};</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10.5pt; mso-char-indent-count: 1.0"><span lang=EN-US>Node list;<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">搞定了</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这样一看</span> <span lang=EN-US>C++</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的确实在代码的层面上简单了，但理解起来却不是很舒服！</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">今天刚接到任务做</span> <span lang=EN-US>Wireless-Lan</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，好长时间没做正事了（这两天主要在写文档）东西还比较多，但是和我一组的</span> <span lang=EN-US>Danel人很好</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，给我讲了下整个</span> <span lang=EN-US>class diagram</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的流程，虽没有</span> <span lang=EN-US>sequence </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">那么容易理解，但我还是懂了。而且我发现他写程序时特别开心，心态很好，这也是我在追求的，慢慢来吧。总监说这周五之前做出点东西，呵呵，不能让他失望呀，过会再看看代码，</span> <span lang=EN-US>GUI</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，我蛮喜欢写的。</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">再说说今天用的那个工具，</span> <span lang=EN-US>SOURCE INSIGHT</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，真爽。看代码的强有力工具。下次给</span> <span lang=EN-US>PASSION</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的兄弟们介绍下。</span> </p>
<img src ="http://www.cppblog.com/iuranus/aggbug/20799.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2007-03-28 19:52 <a href="http://www.cppblog.com/iuranus/archive/2007/03/28/20799.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> C的基本实现</title><link>http://www.cppblog.com/iuranus/archive/2006/12/31/17092.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Sun, 31 Dec 2006 08:00:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2006/12/31/17092.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/17092.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2006/12/31/17092.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/17092.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/17092.html</trackback:ping><description><![CDATA[<h3 class=post-title>C的实现都是有两个不同的环境：翻译与执行<br></h3>
翻译：<br>
<ol>
    <li>把多个源文件编译成目标代码。编译分为预处理器(把类似与#define的替换源文件)，然后解析，也就是来识别代码，大多数错误和警告产生在这步，最后目标代码便生成。这个过程中也可以加入优化器来优化代码。
    <li>把目标代码与标准库函数用链接器捆绑在一起，用于执行。</li>
</ol>
<p>执行：</p>
<ol>
    <li>程序载入内存。
    <li>程序执行。
    <li>程序终止。</li>
</ol>
<img src ="http://www.cppblog.com/iuranus/aggbug/17092.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2006-12-31 16:00 <a href="http://www.cppblog.com/iuranus/archive/2006/12/31/17092.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>