﻿<?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++博客-Sunshine Alike</title><link>http://www.cppblog.com/sunshinealike/</link><description>半完美主义</description><language>zh-cn</language><lastBuildDate>Fri, 03 Apr 2026 18:12:43 GMT</lastBuildDate><pubDate>Fri, 03 Apr 2026 18:12:43 GMT</pubDate><ttl>60</ttl><item><title>SVN的一点使用介绍</title><link>http://www.cppblog.com/sunshinealike/archive/2010/07/30/121695.html</link><dc:creator>Sunshine Alike</dc:creator><author>Sunshine Alike</author><pubDate>Fri, 30 Jul 2010 06:24:00 GMT</pubDate><guid>http://www.cppblog.com/sunshinealike/archive/2010/07/30/121695.html</guid><wfw:comment>http://www.cppblog.com/sunshinealike/comments/121695.html</wfw:comment><comments>http://www.cppblog.com/sunshinealike/archive/2010/07/30/121695.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunshinealike/comments/commentRss/121695.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunshinealike/services/trackbacks/121695.html</trackback:ping><description><![CDATA[SVN：    subversion. Is a version control system, open source, and free.<br /><br />通常有两种使用使用模式：<br />    Lock-modify-Unlock    独占式，代表VSS<br />    Copy-modify-Merge    并行式，CVS/SVN<br />方式1简单易行 ，但是不能支持多人协同工作，其它人在文件被签出后必须要等<br /><br />待它被提交确认后才能进行更改。<br />方式2效率更高一些，但是多人同时进行修改操作时有可能会引发冲突。<br /><br />SVN常用的命令：<br />    checkout, authentication, update, add, delete, commit, rename, import, export...<br /><br />关于命令的一点说明：<br />commit: 不要把垃圾文件提到到服务器，垃圾文件包括中间文件，与具体机器环境相关的文件，可以由其它文件生成的文件等。<br />rename: Windows系统对于文件名不区别大小写而SVN区分，所以在改名时请注意。SVN的rename功能实际是delete再add。<br />import: 用于将本地文件导入SVN，导入内容不包含当前目录。<br />export: 用于导出SVN目录结构，导出的结果不会带有隐藏的.svn目录。<br />resloved: 用于解决完冲突之后确认新的文件。当两个人先后修改了同一部分的内容后，再提交就会产生conflicts，小模型的冲突可以手动使用differ工具修改再resloved确认，大规模的冲突就需要放弃修改结果重新编辑了。<br /><br />Log Message：<br />每次提交的时候都应该写上log，来说明所做的改动，可自己定义某种log格式。<br /><br />属性：<br />SVN中可给目录增加property，比较重要的属性是external，这用来表示一个外部引用，使用方法为：FloderName    URL，结果是在目录下创建一个以URL地址为内容的文件夹。external link始终保持最新，只要修改原始内容，所有的引用都会更新。这很适合来管理系统的公共部分的内容。<br /><br /><b>tag</b>：一个非常有用的命令，用来创建一个系统的快照，把所有的文件锁定到某一个指定的版本号。需要注意的是在tagging的时候external link仍然会保持到最新的版本，所以在tagging之前需要<b>手动指定一个external的版本号</b>，在URL前面加上-r xxx来指定是哪个版本的external。并在tagging完成之后<b>还原</b>这些external，否则它们就不始终保持到最新的版本。<img src ="http://www.cppblog.com/sunshinealike/aggbug/121695.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunshinealike/" target="_blank">Sunshine Alike</a> 2010-07-30 14:24 <a href="http://www.cppblog.com/sunshinealike/archive/2010/07/30/121695.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows动态链接库DLL[实践]</title><link>http://www.cppblog.com/sunshinealike/archive/2010/07/08/119658.html</link><dc:creator>Sunshine Alike</dc:creator><author>Sunshine Alike</author><pubDate>Wed, 07 Jul 2010 16:24:00 GMT</pubDate><guid>http://www.cppblog.com/sunshinealike/archive/2010/07/08/119658.html</guid><wfw:comment>http://www.cppblog.com/sunshinealike/comments/119658.html</wfw:comment><comments>http://www.cppblog.com/sunshinealike/archive/2010/07/08/119658.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunshinealike/comments/commentRss/119658.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunshinealike/services/trackbacks/119658.html</trackback:ping><description><![CDATA[一直对动态链接库这个东西很陌生，今天刚好调试别人写的一个DLL项目，顺便就来研究一下下。<br />动态链接库的原理，好处那些就先不说了，直接来看怎么使用。<br />首先写一个动态链接库，其中<span style="color: rgb(0, 0, 0);"> __declspec(dllexport)是用于MS编译器的一个关键字，用来将DLL中的内容导出而不需要.def文件了。<br />下面的cpp里就函数的定义了，DllMain函数跟普通的win32 console的main函数很像。<br />使用cl /c DLLImplement.cpp<br />link /dll DLLImplement.obj<br />就可以得到一个DLLImplement.dll顺便也会导出一个</span><span style="color: rgb(0, 0, 0);">DLLImplement.</span><span style="color: rgb(0, 0, 0);">lib这个跟静态链接库很像的东西，实际上它的作用只是导出那些方法和变量的名字。<br /><br /></span><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 128);">1</span> <span style="color: rgb(0, 0, 255);">extern</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">C</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">2</span> <span style="color: rgb(0, 0, 0);">{<br /></span><span style="color: rgb(0, 128, 128);">3</span> <span style="color: rgb(0, 0, 0);">    __declspec(dllexport) </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> Set(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i);<br /></span><span style="color: rgb(0, 128, 128);">4</span> <span style="color: rgb(0, 0, 0);">    __declspec(dllexport) </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> Get();<br /></span><span style="color: rgb(0, 128, 128);">5</span> <span style="color: rgb(0, 0, 0);">    __declspec(dllexport) </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> SayHello();<br /></span><span style="color: rgb(0, 128, 128);">6</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">7</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> value;<br /></span><span style="color: rgb(0, 128, 128);">8</span> <span style="color: rgb(0, 0, 0);">}</span></div><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">iostream</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">objbase.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">DLLHeader.h</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> Set(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i)<br /></span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);">{<br /></span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);">    value </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> i;<br /></span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 0, 0);">}<br /></span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> Get()<br /></span><span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);">{<br /></span><span style="color: rgb(0, 128, 128);">12</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> value;<br /></span><span style="color: rgb(0, 128, 128);">13</span> <span style="color: rgb(0, 0, 0);">}<br /></span><span style="color: rgb(0, 128, 128);">14</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> SayHello()<br /></span><span style="color: rgb(0, 128, 128);">15</span> <span style="color: rgb(0, 0, 0);">{<br /></span><span style="color: rgb(0, 128, 128);">16</span> <span style="color: rgb(0, 0, 0);">    std::cout</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Hello, I'm DLL, value is </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">value</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">std::endl;<br /></span><span style="color: rgb(0, 128, 128);">17</span> <span style="color: rgb(0, 0, 0);">}<br /></span><span style="color: rgb(0, 128, 128);">18</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">19</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">20</span> <span style="color: rgb(0, 0, 0);">BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> lpReserved)<br /></span><span style="color: rgb(0, 128, 128);">21</span> <span style="color: rgb(0, 0, 0);">{<br /></span><span style="color: rgb(0, 128, 128);">22</span> <span style="color: rgb(0, 0, 0);">    HANDLE g_hModule;<br /></span><span style="color: rgb(0, 128, 128);">23</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">24</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">switch</span><span style="color: rgb(0, 0, 0);">(dwReason)<br /></span><span style="color: rgb(0, 128, 128);">25</span> <span style="color: rgb(0, 0, 0);">    {<br /></span><span style="color: rgb(0, 128, 128);">26</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">case</span><span style="color: rgb(0, 0, 0);"> DLL_PROCESS_ATTACH:<br /></span><span style="color: rgb(0, 128, 128);">27</span> <span style="color: rgb(0, 0, 0);">       std::cout</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">DLL is attached!</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">std::endl;<br /></span><span style="color: rgb(0, 128, 128);">28</span> <span style="color: rgb(0, 0, 0);">       g_hModule </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (HINSTANCE)hModule;<br /></span><span style="color: rgb(0, 128, 128);">29</span> <span style="color: rgb(0, 0, 0);">       </span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">30</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">31</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">case</span><span style="color: rgb(0, 0, 0);"> DLL_PROCESS_DETACH:<br /></span><span style="color: rgb(0, 128, 128);">32</span> <span style="color: rgb(0, 0, 0);">       std::cout</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">DLL is detached!</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">std::endl;<br /></span><span style="color: rgb(0, 128, 128);">33</span> <span style="color: rgb(0, 0, 0);">       g_hModule</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">NULL;<br /></span><span style="color: rgb(0, 128, 128);">34</span> <span style="color: rgb(0, 0, 0);">       </span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">35</span> <span style="color: rgb(0, 0, 0);">    }<br /></span><span style="color: rgb(0, 128, 128);">36</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">37</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> TRUE;<br /></span><span style="color: rgb(0, 128, 128);">38</span> <span style="color: rgb(0, 0, 0);">}<br /></span><span style="color: rgb(0, 128, 128);">39</span> <span style="color: rgb(0, 0, 0);"></span></div><br /><br />使用DLL的方法，有3种：使用def文件/使用LoadLibrary和GetProcAddress方法/使用导出的lib配合头文件。<br />第一种太麻烦这里不介绍，只说明一下后两种的使用方法。<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">iostream</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">windows.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 0);">typedef </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">SET)(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);">typedef </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">GET)(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);">typedef </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">SAYHELLO)(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> main(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> argc, </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);">argv)<br /></span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 0, 0);">{<br /></span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);">    SET pSet </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);">    GET pGet </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">12</span> <span style="color: rgb(0, 0, 0);">    SAYHELLO pSayHello </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">13</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">14</span> <span style="color: rgb(0, 0, 0);">    HINSTANCE hinst</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">::LoadLibrary(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">DLLImplement.dll</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">15</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> hinst)<br /></span><span style="color: rgb(0, 128, 128);">16</span> <span style="color: rgb(0, 0, 0);">    {<br /></span><span style="color: rgb(0, 128, 128);">17</span> <span style="color: rgb(0, 0, 0);">        std::cout</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">load dll failed!</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">std::endl;<br /></span><span style="color: rgb(0, 128, 128);">18</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">19</span> <span style="color: rgb(0, 0, 0);">    }<br /></span><span style="color: rgb(0, 128, 128);">20</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">21</span> <span style="color: rgb(0, 0, 0);">    pSet </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (SET)GetProcAddress(hinst, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Set</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">22</span> <span style="color: rgb(0, 0, 0);">    pGet </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (GET)GetProcAddress(hinst, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Get</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">23</span> <span style="color: rgb(0, 0, 0);">    pSayHello </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (SAYHELLO)GetProcAddress(hinst, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">SayHello</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">24</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">25</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> pSet </span><span style="color: rgb(0, 0, 0);">||</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> pGet </span><span style="color: rgb(0, 0, 0);">||</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> pSayHello)<br /></span><span style="color: rgb(0, 128, 128);">26</span> <span style="color: rgb(0, 0, 0);">    {<br /></span><span style="color: rgb(0, 128, 128);">27</span> <span style="color: rgb(0, 0, 0);">        std::cout</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">get function failed!</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">std::endl;<br /></span><span style="color: rgb(0, 128, 128);">28</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">29</span> <span style="color: rgb(0, 0, 0);">    }<br /></span><span style="color: rgb(0, 128, 128);">30</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">31</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">ready to call the function</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 128, 128);">32</span> <span style="color: rgb(0, 128, 0);"></span><span style="color: rgb(0, 0, 0);">    (</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">pSet)(</span><span style="color: rgb(0, 0, 0);">10</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">33</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">pGet)();<br /></span><span style="color: rgb(0, 128, 128);">34</span> <span style="color: rgb(0, 0, 0);">    std::cout</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Get value from dll, value is </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">i</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">std::endl;<br /></span><span style="color: rgb(0, 128, 128);">35</span> <span style="color: rgb(0, 0, 0);">    (</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">pSayHello)();<br /></span><span style="color: rgb(0, 128, 128);">36</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">37</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">38</span> <span style="color: rgb(0, 0, 0);">}</span></div>这种调用方法属于显示调用，使用的时候需要知道DLL文件的路径，还有DLL里面的方法的名字，还是有点不太方便。更多的时候，都是使用最后一种隐式调用的方法，即配合头文件和导出的lib，需要在进行链接的时候加入DLLImplement.lib即可，方法如下：<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">iostream</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">DLLHeader.h</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">namespace</span><span style="color: rgb(0, 0, 0);"> std;<br /></span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> main (</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> argc, </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);">argv)<br /></span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);">{<br /></span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 0, 0);">    Set(</span><span style="color: rgb(0, 0, 0);">100</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);">    cout</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Set value in DLL</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">endl;<br /></span><span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Get();<br /></span><span style="color: rgb(0, 128, 128);">12</span> <span style="color: rgb(0, 0, 0);">    cout</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Get value in DLL, value is </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">i</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">endl;<br /></span><span style="color: rgb(0, 128, 128);">13</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">14</span> <span style="color: rgb(0, 0, 0);">    SayHello();<br /></span><span style="color: rgb(0, 128, 128);">15</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">16</span> <span style="color: rgb(0, 0, 0);">}</span></div>到这里对DLL有了一个大概的感性认识，具体的理论性的知识，等有机会慢慢再写出来。<br /><br />抱怨一句，最近有点懒了，想要写的日志都没写。<br />找实习也麻烦，写代码肩膀脖子酸痛。<br />IT民工的命咋就这么苦哩。<br /><img src ="http://www.cppblog.com/sunshinealike/aggbug/119658.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunshinealike/" target="_blank">Sunshine Alike</a> 2010-07-08 00:24 <a href="http://www.cppblog.com/sunshinealike/archive/2010/07/08/119658.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python编程练习一：StaffSalaryApp</title><link>http://www.cppblog.com/sunshinealike/archive/2010/04/23/113343.html</link><dc:creator>Sunshine Alike</dc:creator><author>Sunshine Alike</author><pubDate>Fri, 23 Apr 2010 08:30:00 GMT</pubDate><guid>http://www.cppblog.com/sunshinealike/archive/2010/04/23/113343.html</guid><wfw:comment>http://www.cppblog.com/sunshinealike/comments/113343.html</wfw:comment><comments>http://www.cppblog.com/sunshinealike/archive/2010/04/23/113343.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunshinealike/comments/commentRss/113343.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunshinealike/services/trackbacks/113343.html</trackback:ping><description><![CDATA[学习了一些Python的基础知识之后，就开始来实践吧。<br />上手非常简单，有过一定编程经验的人大约可以在几个小时之内掌握基本的Python编程方法。<br />正好在学习设计模式课程，会有几次课程作业，就直接拿过来权当Python的一次编程练习了<br />第一次任务简介：<br />实现一个管理雇员薪水的工具，可以打印出员工的薪水信息。<br />雇员分为普通和经理，各自有不同的薪水计算方法。<br /><br />Ok，Let's go！<br />首先复习一下Python里的面向对象相关知识，定义一个雇员的基类EmployeeBase<br />并且在__init__方法里定义了三个成员name, base_salary和overtime_days<br />需要注意的就是所有的类成员方法在声明的时候都需要有一个默认的参数self，这个相当于this指针的东西必须要写上，而且访问类成员或者方法也都要加上这个前缀，不然会出错。<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 128);">1</span> <span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> EmployeeBase():<br /></span><span style="color: rgb(0, 128, 128);">2</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(128, 0, 0);">"""</span><span style="color: rgb(128, 0, 0);">Base class of all staffs</span><span style="color: rgb(128, 0, 0);">"""</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">3</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">__init__</span><span style="color: rgb(0, 0, 0);">(self, name </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">, basesalary </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> 0, overtime </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> 0):<br /></span><span style="color: rgb(0, 128, 128);">4</span> <span style="color: rgb(0, 0, 0);">        self.name </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> name<br /></span><span style="color: rgb(0, 128, 128);">5</span> <span style="color: rgb(0, 0, 0);">        self.base_salary </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> basesalary<br /></span><span style="color: rgb(0, 128, 128);">6</span> <span style="color: rgb(0, 0, 0);">        self.overtime_days </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> overtime<br /></span><span style="color: rgb(0, 128, 128);">7</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> GetName(self):<br /></span><span style="color: rgb(0, 128, 128);">8</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> self.name</span></div><br />接下来就是普通雇员类Employee，继承的语法：<span style="color: rgb(0, 0, 0);">Employee(EmployeeBase)<br />以及类的__doc__，养成写注释的习惯。<br /></span><b><span style="color: rgb(0, 0, 0);"> Line 6：<br /></span></b><span style="color: rgb(0, 0, 0);">__init__并不是构造函数，并且Python里也没有构造函数这个概念。所以要手动的调用基类的__init__方法</span><b><span style="color: rgb(0, 0, 0);"></span></b><br />GetSalary中计算薪水，普通雇员的加班工资是双倍计算的。<br /><span style="color: rgb(0, 0, 0);"><br /></span><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Employee(EmployeeBase):<br /></span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(128, 0, 0);">"""</span><span style="color: rgb(128, 0, 0);">Common employee class derived from EmployeeBase.<br /></span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(128, 0, 0);">    A employee can has overtime salary, every overtime work's salary will be doubled<br /></span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(128, 0, 0);">    </span><span style="color: rgb(128, 0, 0);">"""</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">__init__</span><span style="color: rgb(0, 0, 0);">(self, name</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(128, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">, basesalary</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">0, overtime</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">0):<br /></span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);">        EmployeeBase.</span><span style="color: rgb(128, 0, 128);">__init__</span><span style="color: rgb(0, 0, 0);">(self,name,basesalary,overtime)<br /></span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> GetStaffType(self):<br /></span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">Employee</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> GetSalary(self):<br /></span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> self.base_salary </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> self.base_salary</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">30</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">self.overtime_days<br /></span><span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> GetSalaryInfo(self):<br /></span><span style="color: rgb(0, 128, 128);">12</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> self.name </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);"> : </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> self.GetStaffType()</span><span style="color: rgb(0, 128, 128);"></span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);"> : </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> str(self.GetSalary())</span></div><br />到这里，雇员类已经完成，下面就是——<b>单元测试</b>。一般我以前写程序都很少写单元测试的，因为很费时，要写很多测试的代码。<br />但是这里我想特别尝试一下，以展现Python里的各种特性和工具。<br />新版本的Python里有一个专门用于测试的unittest模块，导入就可以使用了，下面新建一个Testsalary.py进行单元测试。<br />首先unittest模块里有一个测试用例的基类<b>TestCase</b>，我们只要在TestCase的派生类里定义自己的测试用例方法就可以使用了，这些测试用命方法甚至都不需要自己调用，只要方法<b>名字以test开头</b>，TestCase就会自动的调用它们。<br />在下面的测试代码中，我定义了testNoneEmployee等几个测试方法，主要是使用了TestCase里的<b>assertEqual</b>方法。<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(128, 0, 0);">"""</span><span style="color: rgb(128, 0, 0);">Unit test for salary.py</span><span style="color: rgb(128, 0, 0);">"""</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> unittest<br /></span><span style="color: rgb(0, 0, 255);">from</span><span style="color: rgb(0, 0, 0);"> salary </span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 0);">Employee<br /><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> TestEmployee(unittest.TestCase):<br />    </span><span style="color: rgb(128, 0, 0);">"""</span><span style="color: rgb(128, 0, 0);">Unit test for clas Employee</span><span style="color: rgb(128, 0, 0);">"""</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> testNoneEmployee(self):<br />        e </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Employee()<br />        self.assertEqual(</span><span style="color: rgb(128, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">,e.GetName())<br />        self.assertEqual(0,e.GetSalary())<br />        self.assertEqual(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">Employee</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,e.GetStaffType())<br />    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> testBaseSalary(self):<br />        e </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Employee(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">emp</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">)<br />        self.assertEqual(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">emp</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,e.GetName())<br />        self.assertEqual(</span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">,e.GetSalary())<br />        self.assertEqual(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">Employee</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,e.GetStaffType())<br />    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> testNoOvertime(self):<br />        e </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Employee(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">emp</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">, 0)<br />        self.assertEqual(</span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">,e.GetSalary())<br />        self.assertEqual(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">emp : Employee : 300</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, e.GetSalaryInfo())<br />    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> testOvertime1(self):<br />        e </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Employee(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">emp</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">)<br />        self.assertEqual(</span><span style="color: rgb(0, 0, 0);">320</span><span style="color: rgb(0, 0, 0);">,e.GetSalary())<br />        self.assertEqual(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">emp : Employee : 320</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, e.GetSalaryInfo())<br />    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> testOvertime2(self):<br />        e </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Employee(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">emp</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">)<br />        self.assertEqual(</span><span style="color: rgb(0, 0, 0);">400</span><span style="color: rgb(0, 0, 0);">,e.GetSalary())<br />        self.assertEqual(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">emp : Employee : 400</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, e.GetSalaryInfo())<br />        <br /></span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">__name__</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">__main__</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:<br />    unittest.main()</span></div>运行之，出现结果：<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">----------------------------------------------------------------------</span><span style="color: rgb(0, 0, 0);"><br />Ran </span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);"> tests </span><span style="color: rgb(0, 0, 255);">in</span><span style="color: rgb(0, 0, 0);"> 0.007s<br /><br />OK</span></div>全部通过，太没意思了，想着要加点什么好呢。下面我对构造Employee的时候加上参数的检查，不允许不正确的参数输入，例如名字太长，工资和加班天数为负数等。我希望在试图用这些不正确的参数进行创建Employee对象的时候出现异常。<br />在测试代码中加入另两个方法，使用了TestCase里的另一个方法<b>assertRaises</b>，这个方法可以检测被测对象是否按抛出了预期的异常。这个方法接受一个异常类型，和一个会产生这种异常的“对象”，通常是一个函数，以及它们的参数<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> testInvalidName(self):<br />        self.assertRaises(InvalidName, Employee, </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">name too long</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)<br />    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> testInvalidInput1(self):<br />        self.assertRaises(InvalidInput, Employee, </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">emp</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">)<br />    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> testInvalidInput2(self):<br />        self.assertRaises(InvalidInput, Employee, </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">emp</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">300</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">)</span></div>两种异常类的名字分别叫InvalidName和InvalidInput，这下测试通不过了。下面就需要修改Employee类，首先提一下Python里的异常处理，使用try...except...处理异常，raise抛出异常，finally可以用来做一些善后处理工作。<br />下面先要定义上面用到的这两种异常，InvalidName和InvalidInput，这里简单的继承一下Python里的Exception类就可以了，然后修改Employee的__init__方法，进行参数的查检，修正后如下：<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);">new type of Expceptions</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> InvalidName(Exception):</span><span style="color: rgb(0, 0, 255);">pass</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> InvalidInput(Exception):</span><span style="color: rgb(0, 0, 255);">pass</span><span style="color: rgb(0, 0, 0);"><br /><br /><br /></span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);">－－－－－－－－－－－－－－－－－－－－－－</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"><br /><br />    </span><span style="color: rgb(0, 0, 255);">def</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">__init__</span><span style="color: rgb(0, 0, 0);">(self, name</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(128, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">, basesalary</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">0, overtime</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">0):<br />        </span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);">raise exceptions if input is invalidate</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> len(name) </span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">8</span><span style="color: rgb(0, 0, 0);">:<br />            </span><span style="color: rgb(0, 0, 255);">raise</span><span style="color: rgb(0, 0, 0);"> InvalidName, </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">Error: Name too long!</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> basesalary </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);"> 0 </span><span style="color: rgb(0, 0, 255);">or</span><span style="color: rgb(0, 0, 0);"> basesalary </span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">300000</span><span style="color: rgb(0, 0, 0);">:<br />            </span><span style="color: rgb(0, 0, 255);">raise</span><span style="color: rgb(0, 0, 0);"> InvalidInput, </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">Error: Base salary should between 0~300000!</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);">use int(overtime) != overtime to check if the input is int</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> overtime </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);"> 0 </span><span style="color: rgb(0, 0, 255);">or</span><span style="color: rgb(0, 0, 0);"> overtime  </span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">31</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">or</span><span style="color: rgb(0, 0, 0);"> int(overtime) </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> overtime:<br />            </span><span style="color: rgb(0, 0, 255);">raise</span><span style="color: rgb(0, 0, 0);"> InvalidInput, </span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">Error: Overtime should between 0~31!</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />        EmployeeBase.</span><span style="color: rgb(128, 0, 128);">__init__</span><span style="color: rgb(0, 0, 0);">(self,name,basesalary,overtime)</span></div>ps：异常类型后面的文字是为了给，异常处理提供信息用的。<br /><br />OK，第一步顺利完成，下面就是经理类。经理的工资由加班工资和绩效组成，加班工资只跟经理的等级有关，它与绩效工资都是一个固定值，基本上没有什么难度。<br /><br /><br /><br /><br /><br /><img src ="http://www.cppblog.com/sunshinealike/aggbug/113343.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunshinealike/" target="_blank">Sunshine Alike</a> 2010-04-23 16:30 <a href="http://www.cppblog.com/sunshinealike/archive/2010/04/23/113343.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一点软件设计的体会：设计模式和UML</title><link>http://www.cppblog.com/sunshinealike/archive/2010/04/10/112162.html</link><dc:creator>Sunshine Alike</dc:creator><author>Sunshine Alike</author><pubDate>Sat, 10 Apr 2010 05:19:00 GMT</pubDate><guid>http://www.cppblog.com/sunshinealike/archive/2010/04/10/112162.html</guid><wfw:comment>http://www.cppblog.com/sunshinealike/comments/112162.html</wfw:comment><comments>http://www.cppblog.com/sunshinealike/archive/2010/04/10/112162.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunshinealike/comments/commentRss/112162.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunshinealike/services/trackbacks/112162.html</trackback:ping><description><![CDATA[这学期开始认真学习设计模式这门课，老师课上说了一句话：在设计模式出现以前，软件开发是门艺术，只有那些有天赋的程序员才能写有优雅的代码；设计模式被人们总结出来之后，软件开发就成了一门技术了，有着固定的模式可以参考，没有天赋的程序员也可以写出很好的代码。<br />先不管这句话的正确与否，但是有一点是确定的，软件的开发过程中，设计是非常重要的。有一个好的设计能够将软件开发失败的机率降到最低。<br />设计模式不应该被视为软件开发的说明书，照着那一条一条的模式套用并不一定能写出来好的程序，正确的态度应该是把它们作为软件设计的经验和建议来看。<br />最近看了下那本《敏捷软件开发：原则、模式与实践》，感觉确实是本好书，可以看出来作者对软件开发的功力非常丰富。我发现作者在说明软件开发过程的时候大量使用了UML，以前我都认识这些东西很虚，很麻烦。现在看这本书的时候却有点了不同的体会，哈哈，看来是我以前层次太低了。UML实在是一个好东西，清晰明了，用来描述复杂的系统的时候真有种拨云见日的感觉。<br /><br />下面简单写一下UML的基本知识：<br />1.识别参与者<br />2.抽取用例<br />用例中有两点需要说明一下：扩展(extension)/包含(include)<br />扩展：它们之间互不引用，仅仅插入到被扩展用例中<br />包含：包含用例会<b>引用</b>被包含的用例<br />基本用例完成之后，可以根据参与者将其分类组织起来，形成系统的边界图来汇总显示。<br /><br />3.领域模式(domain)<br />这是一种类似于UML类图,但是它们之间有很大的差别，它并不会对应于编码中的类(class)。<br />4.类之间的关系<br />关联：以一条线连接两个类表示，表示它们之间相互包含。更常见的是一种带箭头单向关联关系。<br />聚合：以一个白色菱形箭头表示类之间的“整体/局部”关系，同样聚合关系的一个变体“组合”，以一个黑色菱形箭头表示，这也是一种“整体/局部”关系，但是“部分”不能脱离“整体”而存在，“整体”也必须负责管理“部分”的生存期。<br />举例：家庭和人是聚合关系，而电脑与CPU是组合关系<br /><img src ="http://www.cppblog.com/sunshinealike/aggbug/112162.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunshinealike/" target="_blank">Sunshine Alike</a> 2010-04-10 13:19 <a href="http://www.cppblog.com/sunshinealike/archive/2010/04/10/112162.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个小故事：老师在毕业典礼上的讲话</title><link>http://www.cppblog.com/sunshinealike/archive/2010/04/10/112153.html</link><dc:creator>Sunshine Alike</dc:creator><author>Sunshine Alike</author><pubDate>Sat, 10 Apr 2010 04:23:00 GMT</pubDate><guid>http://www.cppblog.com/sunshinealike/archive/2010/04/10/112153.html</guid><wfw:comment>http://www.cppblog.com/sunshinealike/comments/112153.html</wfw:comment><comments>http://www.cppblog.com/sunshinealike/archive/2010/04/10/112153.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunshinealike/comments/commentRss/112153.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunshinealike/services/trackbacks/112153.html</trackback:ping><description><![CDATA[   其一，“世界上第一高峰是哪座山?”大家哄堂大笑：“珠穆朗玛峰!”老师追问：“第二高峰呢?”同学们面面相觑，无人应声。老师在黑板上写：“屈居第二与默默无闻毫无区别。 ” <br />  <br />   其二，“有人要烧壶开水，等生好火发现柴不够，他该怎么办?”有的说赶快去找，有的说去借、去买。老师说：“为什么不把壶里的水倒掉一些?”大家一听，表示佩服。 <br />  <br />   其三，“古代有一人，想学立身的本领。经过反复比较，决心去学屠龙之技。他拜名师，日夜苦练，终有所成。他会怎么样呢?“同学们兴致勃勃，说他能成为英雄、明星，受世人崇拜。老师摇头：“这个人一定会潦倒一生，因为世上根本就没有龙。” <br />  <br />   你们应该要学会“如何做人、做事、做学问”：<b><br />   做人要力求出色，勇争第一，这样别人才能发现你、记住你；<br />   做事要敢于创新，方法灵活，千万不可墨守成规；<br />   做学问要学以致用，要懂得将知识转化为效益，闭门造车没有路。</b><img src ="http://www.cppblog.com/sunshinealike/aggbug/112153.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunshinealike/" target="_blank">Sunshine Alike</a> 2010-04-10 12:23 <a href="http://www.cppblog.com/sunshinealike/archive/2010/04/10/112153.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>有一些想法，慢慢开始整理一下</title><link>http://www.cppblog.com/sunshinealike/archive/2010/04/05/111701.html</link><dc:creator>Sunshine Alike</dc:creator><author>Sunshine Alike</author><pubDate>Mon, 05 Apr 2010 13:27:00 GMT</pubDate><guid>http://www.cppblog.com/sunshinealike/archive/2010/04/05/111701.html</guid><wfw:comment>http://www.cppblog.com/sunshinealike/comments/111701.html</wfw:comment><comments>http://www.cppblog.com/sunshinealike/archive/2010/04/05/111701.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunshinealike/comments/commentRss/111701.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunshinealike/services/trackbacks/111701.html</trackback:ping><description><![CDATA[Dare比赛的事情暂时告下一段落，虽然当时热情挺高，但是事过一半才发现原来其它人并不是都这么想的。自从上了大学之后越发的感觉到再也很难跟别人想到一块去了，单纯的年代已经远去喽。近来听说一个发小都要结婚了，啧啧，我这八字还没一撇呢。。。<br /><br />以前一直觉得父母跟自己和不来，但是现在突然发现，是自己太固执了。以前总觉得他们的处事方式不顺眼，现在自己经历过一些事情之后，才知道原来前人们留下的经验不可能都是吃饱了撑的没事干拍拍脑门凭空想出来的，今后还需多向他们请教为人处事的经验。<br /><br />再就是近来感觉常忘事，本来自制力就不够。一疏忽就浪费不少时间，以致于先前相好的计划常常完成不了。不应该啊不应该，以后应该多写计划，写下来！把任务分类别、管理好自己的时间。离毕业不远了，把握当下！！<br /><img src ="http://www.cppblog.com/sunshinealike/aggbug/111701.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunshinealike/" target="_blank">Sunshine Alike</a> 2010-04-05 21:27 <a href="http://www.cppblog.com/sunshinealike/archive/2010/04/05/111701.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Command和ActiveObjcet模式</title><link>http://www.cppblog.com/sunshinealike/archive/2010/04/02/111453.html</link><dc:creator>Sunshine Alike</dc:creator><author>Sunshine Alike</author><pubDate>Fri, 02 Apr 2010 09:04:00 GMT</pubDate><guid>http://www.cppblog.com/sunshinealike/archive/2010/04/02/111453.html</guid><wfw:comment>http://www.cppblog.com/sunshinealike/comments/111453.html</wfw:comment><comments>http://www.cppblog.com/sunshinealike/archive/2010/04/02/111453.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunshinealike/comments/commentRss/111453.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunshinealike/services/trackbacks/111453.html</trackback:ping><description><![CDATA[
		<p>Command模式，一个传说中非常简单的模式，但是其应用还真不简单。<br />通过接口将某些方法封装起来以达到解除系统逻辑互联关系的耦合的效果，并且实现了Command接口的类对象可以在系统中自由的重新组合，参数传递也非常方便，为系统带来灵活性的提升。<br />其应用范围包括数据库的事务操作、设备控制、多线程核心以及GUI的do/undo操作。<br /><br />ActiveObject模式是使用Command模式的应用之一，这是实现<strong>多线程控制</strong>的一种技术。<br /><br />下面是一个简单的实例：<br />1. 一个Command接口，定义了Execute方法。<br />2. 两个类SleepingCommand和PrinterCommand实现了Command中的Execute方法。<br />   在PrinterCommand中调用Execute时打印一个字符并创建一个新的PrinterCommand在指定的延时后执行。<br />   SleepingCommand表示一个睡眠中的Command，他在执行时只是简单的将自己放到链表末尾直到等待的事件（设定的延时到来）发生它才会将自己唤醒等待下一步执行。<br />3. 一个StopCommand类，实现了用于终止Command链循环的Execute方法。<br />4. 一个ActiveObjectManager对象，维护了一个Command对象链表，用户可以像Manager中AddCommand对象或者便利链表并依次调用Command对象的Execute方法执行任务。</p>
<img src ="http://www.cppblog.com/sunshinealike/aggbug/111453.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunshinealike/" target="_blank">Sunshine Alike</a> 2010-04-02 17:04 <a href="http://www.cppblog.com/sunshinealike/archive/2010/04/02/111453.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python！Python！！</title><link>http://www.cppblog.com/sunshinealike/archive/2010/03/30/111060.html</link><dc:creator>Sunshine Alike</dc:creator><author>Sunshine Alike</author><pubDate>Tue, 30 Mar 2010 14:34:00 GMT</pubDate><guid>http://www.cppblog.com/sunshinealike/archive/2010/03/30/111060.html</guid><wfw:comment>http://www.cppblog.com/sunshinealike/comments/111060.html</wfw:comment><comments>http://www.cppblog.com/sunshinealike/archive/2010/03/30/111060.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunshinealike/comments/commentRss/111060.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunshinealike/services/trackbacks/111060.html</trackback:ping><description><![CDATA[突然一时兴起找了个Python的Tutorial看了一下下，哈哈，感觉非常好，很小巧很讨喜的语言，比较有特点。第一印象是很简单，语法简洁而又功能强大，准备要尝试学一下。<br /><br />下面贴一点学习的笔记：<br /><br /><font size="5">一、基本知识</font><br />Python同时即是脚本解释器，又是一个可以运行命令行的shell。在shell里可以计算任务Python表达式，甚至包括变量赋值，这些变量在shell打开时一直有效，关闭时丢失数据。<br /><br />函数声明，以def开始，函数名，参数，冒号后面跟函数体。需要注意的是Python里的格式都以缩进的形式来表达，没有类C/C++中的大括号。另外函数
不需要指定返回值类型，实际上，如果函数有return语句，它将返回指定类型值，否则返回None（Python的空值）。<br /><br />Python即是动态语言，它<b>不需要显示数据类型声明</b>，赋值的同时即完成变量声明。又是强类型语言，一个变量一旦获得一个数据类型，它实际上就一直是这个类型的了。<br /><br />Python里的“对象”概念，这里的“对象”不同于以前接触到的OO里的对象，Python里的对象定义更为广泛。一个程序块，一个变量，甚至一个字符串都可以是一个对象。其具体含义还需要根据上下文来判断。<br /><br /><b>三种重要的内置数据类型：Dictionary，List，Tuple：</b><br /><b>Dictionary</b>对应于C++中的map和Java中的hashtable，也就是一个键值对集合。<br /><b>List</b>对应于C++中的vector和java中的ArrayList，一个可以动态自动扩展的数组。<br /><b>Tuple</b>是一个不可变的list，一旦创建就不能以方式改变它，但是好在Python提供了在Tuple和List之间相互转换的函数。<br />需要注意的是List和Tuple是可以存储混合类型的数组的，并且都可以通过索引取值（包括负的索引值，其表示从逆序取值）<br /><b><br />For语句：</b><br />Python里的for语句不同于C/C++中的for，更类似于C#中的<code>foreach</code>循环或者是Java中的<code>for (int i : IntArray)</code>。Python的for语句需要配合一个range函数使用，它有三个参数，并返回一个Tupe数组用于表示索引，三个参数是start,stop,step，例如range（0，5，1）则返回[0，1，2，3，4]；range（5，0，－1）则返回[5，4，3，2，1]。<br /><br /><b>字符串格式化：</b><br />与C中类似%d，%f，%s等等，通过字符串的join函数可以方便的将list的内容合并成字符串。<br /><br /><b>and/or：</b><br />and和or负责执行布尔逻辑运算，但是它们不返回布尔值而是返回它们实际进行比较的值之一。非空的对象被认为是真，空对象则被认为是假。<b>and运算会返回第一个假值，而or运算返回第一个真值，其它部分都不会被计算到</b>。<br /><br /><b>lambda函数：</b><br />一种快速定义的单行最小函数，只有一行，类似于内联的感觉。例如一个例子：<br />ld = lambda i : i*i<br />ld(10) # == 100<br />理论上lambda函数可以有多个参数（包括可选参数）并且隐含的返回单个表达式的值。<br /><p class="programlisting"><b>两种导入（import）方法：</b></p><p class="programlisting">Python中有两种导入模块的方法： import xx / from xx import yy<br /></p>
它们的差别在于，from xx import
yy这种方式，yy被直接导入到了局部命名空间中（<b>类似于C++中的using</b>），在以后使用yy的时候不再需要（<b>不能</b>）加上模块名称限定。也就是说，如果使用import方式导入模块，在使用
它里面的一个变量的时候，你不得不每次都加上前缀xx.来表示使用的是位于xx模块中的变量，而使用from导入时，则不需要加入前缀。<br /><br /><b>异常处理：</b><br />Python中使用<b>try...except</b>来处理异常，使用<b>raise</b>来引发异常。并且，一个except后面可以跟一个else块来表示没有捕获预期异常时的行为。一个try块后面也可以跟一个<b>finally</b>块来保证一些代码总是被执行到，比如打开文件后的关闭操作。<br /><br /><b>注释：<br /></b>Python里使用<b>#</b>来作为单选注释开始符，使用三个冒号作为多行注释"""content"""，<br />需要注意的是后一种形式的注意经常被用来作为函数或者类的"说明",写在这里的内容可以被其使用者当作参考手册来使用，Ptyhon里所有对象都具有一个内置的<b>__doc__属性</b>，通过它可以查看各个对象的说明，应该养成写__doc__的习惯。一般其格式为<b>首行以大写字母开始，句号结尾。第二行是空行，从第三行开始是详细的描述</b>。<br /><br /><b>引号：<br /></b>Python里有单引号，双引号和三引号。其中<b>单引号和双引号都可以用来表示字符串</b>，例如<br />print 'string' == "string" 将会打印出True<br />设置这两种字符串引号的目的是为了简化引号的表示，例如如果字符串里含有引号本身就需要<b>使用\来进行标识</b>，例如：'let\'s go!'，“he said:\"get out!\"”。<br />如果字符串里含有大量这种情况会显得非常麻烦，可以交替使用单引号和双引号来避免这种情况。上面的例子可以改为："let's go!"，'he said:"get out!"'。<br />而三引号就是用来表示一个多行字符串。它们经常被用来定义<b>文档字符串</b>，它的首行以大写字母开始，句号结尾。第二行是空行，从第三行开始是详细的描述。建议从一开始就遵守这个惯例。<br /><br /><p class="programlisting"><font size="5">二、面向对象</font></p><b>类的定义：</b><br />以class开头，pass表示结束（实际上没有特定的u），例如一个简单的类定义为<br />class Person:<br />    pass<br />如果要表示继承关系只需要将基类用括号回到类名后面即可，Python支持多重继续，每个基类中间以逗号隔开。<br />class Student（Person）：<br />  pass<br />这里的pass语句仅表示占位之用，没有特别的含义。<br /><br /><b>类成员定义：</b><br /><b>__init__</b>方法，这个函数的功能很类似于Java或者C++中的构造函数，但是仍存在一点细小的差别，__init__函数的第一个参数一定是self，类似于C++中的this指针。<br />__init__方法的定义并<b>不是必须的</b>，但是一旦你定义了它，就<b>必须显示的</b>调用父类的__init__方法。<br />需要注意的是，所有的类成员方法都必须定义一个<b>参数（self）</b>，<b>但它的名字不是一定的</b>，其作用类似于C++中的<b>this</b>指针。<br /><b>__del__方法</b>，类似于析构函数，在使用del语句的时候被调用。<br /><br /><b>重载：</b><br />Python的类<b>没有任何形式的函数重载</b>，即一个方法名称只能对应一个方法，如果子类中定义的与基类中同名的方法，则会将其覆盖掉。<br /><br /><b>成员属性：</b><br />Python中有两种类型的成员方法：<b>普通类方法和专用类方法</b>。<br />成员也有两种访问级别：<b>公开的和私有的</b>。<br />其中公开和私有成员的表示没有特别的关键字，只是体现的方法名称上，私有成员的名称以两个短小的下划线作为开始例如：<br />class A:<br />  __privatevalue<br />  publicvalue<br />  def __set(self, v):<br />    __privatevalue = v<br />  def get(self):<br />    return publicvalue<br />  pass<br />并且，一个成员是属于类的还是属于对象的，是通过定义这个变量的域来确定的，定义在类体内的变量由所有成员共享，通过self定义的变量则为成员变量。<br />此外，类的成员方法还分为：<b>普通类方法和专用类方法</b>。普通方法的定义与普通函数定义类似，它是公开的，在类外部可以被调用。而类的<b>专用方法</b>，没有特殊的关键字来表示，只是在方法的名称前后各加上两个短的下划线，例如def __getitem__。这种专用方法是由用户显式调用的，它有点<b>操作符重载</b>的意思在里面，但是功能比操作符重载要强大一些。Python允许我们自己定义需要的类专用方法，例如任何定义了__cmp__方法的类就可以用＝＝进行比较，任何定义了__len__方法的类就可以用len(instance)进行取长度。<br /><br /><font size="5">三、标准库<br /><b><font size="4">1.文件操作</font></b><br /></font>Python中有一个内置函数open可以用来打开文件<br />file = open("pictures/dog.bmp","rb")<br />open函数可以接受三个参数：<b>文件名，模式和缓冲区参数</b>，但是只有每一个参数是必须的，文件会默认以文本方式打开。<br />文件的读取和C中类似，tell()返回当前文件位置，seek来移动文件操作的位置。具体的函数使用方法可以使用print seek.__doc__来查看<br /><br />处理I/O错误：<br />try:<br />  file = open(filename, "rb", 0)<br />  try:<br />    file.seek(-128,2)<br />    data = file.read(128)<br />    file.seek(0,2)<br />    file.write("succeeded")<br />    finally:<br />      file.close()<br />  expect IOError:<br />    pass<br /><br />Python提供了一个os.path模块来进行目录操作，具体使用方法就不详细写出来了，用过几次就记住了。<br /><br /><b><font size="4">2.序列化</font></b><br />标准库里有两个模块都提供这个功能，<b>pickle</b>和<b>cPickle</b>，用于将对象存储到文件中而后再读取出来。<br />但是后者是使用C语言写的，速度要比前面的快很多，但是功能都是一样的。<br />使用也很简便主要就是使用dump和load函数<br /><br />－－－－－－－－－－－－－－－－－－待续－－－－－－－－－－－－－－－－<br /><br /><br /><img src ="http://www.cppblog.com/sunshinealike/aggbug/111060.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunshinealike/" target="_blank">Sunshine Alike</a> 2010-03-30 22:34 <a href="http://www.cppblog.com/sunshinealike/archive/2010/03/30/111060.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Life is Hard!</title><link>http://www.cppblog.com/sunshinealike/archive/2010/03/21/110205.html</link><dc:creator>Sunshine Alike</dc:creator><author>Sunshine Alike</author><pubDate>Sun, 21 Mar 2010 07:17:00 GMT</pubDate><guid>http://www.cppblog.com/sunshinealike/archive/2010/03/21/110205.html</guid><wfw:comment>http://www.cppblog.com/sunshinealike/comments/110205.html</wfw:comment><comments>http://www.cppblog.com/sunshinealike/archive/2010/03/21/110205.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunshinealike/comments/commentRss/110205.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunshinealike/services/trackbacks/110205.html</trackback:ping><description><![CDATA[不到一个月，才开了两个项目，就乱成一锅粥了，真郁闷。<br />一个好的团队真是太重要了，而在学校里，这个太不靠谱了。<br />总有人来混事，总有人来闹矛盾，总有人有这样那样的想法，总有人不理解你，完全无奈了。<br /><br />－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<br />做游戏真是辛苦，需要学的东西太多了，找不到方向<br />现在真是有点理解那句话：“当你把一个兴趣，变成了职业之后，悲剧就开始了！”<br />为了当年心里的兴趣，转了方向来搞游戏，我想现在是遇到瓶颈了，动力不足。。。。<br /><br /><img src ="http://www.cppblog.com/sunshinealike/aggbug/110205.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunshinealike/" target="_blank">Sunshine Alike</a> 2010-03-21 15:17 <a href="http://www.cppblog.com/sunshinealike/archive/2010/03/21/110205.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux Note</title><link>http://www.cppblog.com/sunshinealike/archive/2010/03/14/109696.html</link><dc:creator>Sunshine Alike</dc:creator><author>Sunshine Alike</author><pubDate>Sun, 14 Mar 2010 13:06:00 GMT</pubDate><guid>http://www.cppblog.com/sunshinealike/archive/2010/03/14/109696.html</guid><wfw:comment>http://www.cppblog.com/sunshinealike/comments/109696.html</wfw:comment><comments>http://www.cppblog.com/sunshinealike/archive/2010/03/14/109696.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunshinealike/comments/commentRss/109696.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunshinealike/services/trackbacks/109696.html</trackback:ping><description><![CDATA[最近才开始接触linux系统（Ubuntu 9.10），有些东西容易忘记，备忘之，待续。<br /><br />1.g++编译问题<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">main.cpp</span><span style="color: rgb(0, 128, 0);"></span><br /><span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">iostream</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">namespace</span><span style="color: rgb(0, 0, 0);"> std;<br /><br /></span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">headers</span><span style="color: rgb(0, 128, 0);"></span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> show();<br /><br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> main()<br />{</span><span style="color: rgb(0, 0, 0);"><br />    cout</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">library test function show(): </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br />    show();<br />    </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br />}</span></div><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">libtest.cpp</span><span style="color: rgb(0, 0, 0);"></span><br /><span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">iostream</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">namespace</span><span style="color: rgb(0, 0, 0);"> std;<br /><br /></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> show()<br />{<br />    cout</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">hello library test!</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">endl;<br />}</span></div><br /><b>静态库</b>：<br />首先编译libtest.cpp生成中间文件 <b>libtest.o</b><br />g++ -c libtest.cpp<br />然后将其打包成静态库 <b>staticlib.a<br /></b>ar -rc staticlib.a libtest.o<br />最后使用静态库与main.cpp进行编译得到执行文件<b>staticlib<br /></b>g++ -o staticlib main.cpp staticlib.a<br />运行./staticlib 成功！！<br /><br /><b>动态库：<br /></b>首先同样需要编译生成中间文件<b>libteset.o</b>，但一般加上-fPIC选项。<br />其意思是位置独立代码 ，指示编译程序生成的代码要适合共享库的内容这样的代码能够根据载入内存的位置计算内部地址<br />g++ -c -fPIC libtest.cpp<br />然后打包 生成动态库<b>dynamiclib.so</b><br />g++ -shared libtest.o -o dynamiclib.so<br />最后生成可执行文件dynamiclib<br />g++ -o dynamic main.cpp dynamiclib.so<br />运行./dynamiclib <b>结果出错了，提示找不到动态库。</b><br />原因是linux下动态库不像windows里那样会自动寻找当前目录下的dll，这需要把编译出来的动态库放到系统的 /usr/lib 或 /lib下才能运行程序。<br />或者还可以在编译的时候就指定路径也可以，例如在最后一步的时候：<br />g++ -o dynamic main.cpp <b>./dynamiclib.so<br /></b>再次运行./dynamiclib 成功！！<br /><img src ="http://www.cppblog.com/sunshinealike/aggbug/109696.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunshinealike/" target="_blank">Sunshine Alike</a> 2010-03-14 21:06 <a href="http://www.cppblog.com/sunshinealike/archive/2010/03/14/109696.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>