﻿<?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++博客-ngaut-随笔分类-c/c++/ds</title><link>http://www.cppblog.com/ngaut/category/635.html</link><description>asm/c/c++/......</description><language>zh-cn</language><lastBuildDate>Sun, 31 Aug 2008 23:33:48 GMT</lastBuildDate><pubDate>Sun, 31 Aug 2008 23:33:48 GMT</pubDate><ttl>60</ttl><item><title>[转]Google C++ Testing Framework Primer</title><link>http://www.cppblog.com/ngaut/archive/2008/08/31/60514.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Sun, 31 Aug 2008 12:19:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2008/08/31/60514.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/60514.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2008/08/31/60514.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/60514.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/60514.html</trackback:ping><description><![CDATA[<div id="blog_text" class="cnt">
<p><strong>Google C++ Testing Framework Primer</strong></p>
<p>翻译：<a  href="http://rayleex.spaces.live.com/blog/cns%21C32DFA3924AF2128%21218.entry"><font color="#669966">Ray Li </font></a>(<a  href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#114;&#97;&#121;&#46;&#108;&#101;&#101;&#120;&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;"><font color="#669966">ray.leex@gmail.com</font></a>) <br>
修改日期：2008年7月6日<br>
原文参见：<a  href="http://code.google.com/p/googletest/wiki/GoogleTestPrimer"><font color="#669966">http://code.google.com/p/googletest/wiki/GoogleTestPrimer</font></a></p>
<p><strong>Introduction</strong><strong>：为什么需要</strong><strong>Google C++ </strong><strong>测试框架？</strong></p>
<p>Google C++ 测试框架帮助你更好地编写C++测试。</p>
<p>无论你是在Linux，Windows，还是Mac环境下工作，只要你编写C++代码，Google 测试框架都可以帮上忙。</p>
<p>那么，哪些因素才能构成一个好的测试？以及，Google C++ 测试框架怎样满足这些因素？我们相信：</p>
<ol>
    <li>测试应该是<em>独立</em>、<em>可重复</em>的。因为其他测试成功或失败而导致我们要对自己的测试进行debug是非常痛苦的。Google C++ 测试框架通过将每个测试在不同的对象中运行，使得测试分离开来。当一个测试失败时，Google C++ 测试框架允许你独立运行它以进行快速除错。</li>
    <li>测试应该能够被很好地<em>组织</em>，并反映被测代码的结构。Google C++ 测试框架将测试组织成测试案例，案例中的测试可以共享数据和程序分支。这样一种通用模式能够很容易辨识，使得我们的测试容易维护。当开发人员在项目之间转换，开始在一个新的代码基上开始工作时，这种一致性格外有用。</li>
    <li>测试应该是<em>可移植</em>、<em>可重用</em>的。开源社区有很多平台独立的代码，它们的测试也应该是平台独立的。除开一些特殊情况，Google C++ 测试框架运行在不同的操作系统上、与不同的编译器（gcc、icc、MSVC）搭配，Google C++ 测试框架的测试很容易与不同的配置一起工作。</li>
    <li>当测试失败时，应该提供尽可能多的、关于问题的<em>信息</em>。Google C++ 测试框架在第一个测试失败时不会停下来。相反，它只是将当前测试停止，然后继续接下来的测试。你也可以设置对一些非致命的错误进行报告，并接着进行当前的测试。这样，你就可以在一次&#8220;运行-编辑-编译&#8221;循环中检查到并修复多个bug。</li>
    <li>测试框架应该能将测试编写人员从一些环境维护的工作中解放出来，使他们能够集中精力于测试的<em>内容</em>。Google C++ 测试框架自动记录下所有定义好的测试，不需要用户通过列举来指明哪些测试需要运行。</li>
    <li>测试应该<em>快速</em>。使用Google C++ 测试框架，你可以重用多个测试的共享资源，一次性完成设置/解除设置，而不用使一个测试去依赖另一测试。</li>
</ol>
<p>因为Google C++ 测试框架基于著名的xUnit架构，如果你之前使用过JUnit或PyUnit的话，你将会感觉非常熟悉。如果你没有接触过这些测试框架，它也只会占用你大约10分钟的时间来学习基本概念和上手。所以，让我们开始吧！</p>
<p>Note：本文偶尔会用&#8220;Google Test&#8221;来代指&#8220;Google C++ 测试框架&#8221;。</p>
<p><strong>基本概念</strong></p>
<p>使用Google Test时，你是从编写<em>断言</em>开始的，而断言是一些检查条件是否为真的语句。一个断言的结果可能是成功、非致命失败，或者致命失败。如果一个致命失败出现，他会结束当前的函数；否则，程序继续正常运行。</p>
<p><em>测试</em>使用断言来验证被测代码的行为。如果一个测试崩溃或是出现一个失败的断言，那么，该测试<em>失败</em>；否则该测试<em>成功</em>。</p>
<p>一个测试案例（test case）包含了一个或多个测试。你应该将自己的测试分别归类到测试案例中，以反映被测代码的结构。当测试案例中的多个测试需要共享通用对象和子程序时，你可以把他们放到一个测试固件（<em>test fixture</em>）类中。</p>
<p>一个<em>测试程序</em>可以包含多个测试案例。</p>
<p>从编写单个的断言开始，到创建测试和测试案例，我们将会介绍怎样编写一个测试程序。</p>
<p><strong>断言</strong></p>
<p>Google Test中的断言是一些与函数调用相似的宏。要测试一个类或函数，我们需要对其行为做出断言。当一个断言失败时，Google
Test会在屏幕上输出该代码所在的源文件及其所在的位置行号，以及错误信息。也可以在编写断言时，提供一个自定义的错误信息，这个信息在失败时会被附加
在Google Test的错误信息之后。</p>
<p>断言常常成对出现，它们都测试同一个类或者函数，但对当前功能有着不同的效果。ASSERT_*版本的断言失败时会产生致命失败，并<strong>结束当前函数</strong>。EXPECT_*版本的断言产生非致命失败，而不会中止当前函数。通常更推荐使用EXPECT_*断言，因为它们运行一个测试中可以有不止一个的错误被报告出来。但如果在编写断言如果失败，就没有必要继续往下执行的测试时，你应该使用ASSERT_*断言。</p>
<p>因为失败的ASSERT_*断言会立刻从当前的函数返回，可能会跳过其后的一些的清洁代码，这样也许会导致空间泄漏。根据泄漏本身的特质，这种情况
也许值得修复，也可能不值得我们关心——所以，如果你得到断言错误的同时，还得到了一个堆检查的错误，记住上面我们所说的这一点。</p>
<p>要提供一个自定义的错误消息，只需要使用&lt;&lt;操作符，或一个&lt;&lt;操作符的序列，将其输入到框架定义的宏中。下面是一个例子：</p>
<p>Cpp代码</p>
<ol>
    <li>ASSERT_EQ(x.size(), y.size()) &lt;&lt; "Vectors x and y are of unequal length"; &nbsp;&nbsp;</li>
    <li>for (int i = 0; i &lt; x.size(); ++i) { &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; EXPECT_EQ(x[i], y[i]) &lt;&lt; "Vectors x and y differ at index " &lt;&lt; i; &nbsp;&nbsp;</li>
    <li>}&nbsp;&nbsp;</li>
</ol>
<pre>ASSERT_EQ(x.size(), y.size()) &lt;&lt; "Vectors x and y are of unequal length";<br>for (int i = 0; i &lt; x.size(); ++i) {<br>  EXPECT_EQ(x[i], y[i]) &lt;&lt; "Vectors x and y differ at index " &lt;&lt; i;<br>}</pre>
<p>任何能够被输出到ostream中的信息都可以被输出到一个断言宏中——特别是C字符串和string对象。如果一个宽字符串
（wchar_t*，windows上UNICODE模式TCHAR*或std::wstring）被输出到一个断言中，在打印时它会被转换成UTF-8
编码。</p>
<p><strong>基本断言</strong></p>
<p>下面这些断言实现了基本的true/false条件测试。</p>
<p><strong>致命断言</strong><br>
<strong>非致命断言</strong><br>
<strong>验证条件</strong></p>
<p>ASSERT_TRUE(<em>condition</em>);<br>
EXPECT_TRUE(<em>condition</em>); <br>
<em>condition</em>为真</p>
<p>ASSERT_FALSE(<em>condition</em>); <br>
EXPECT_FALSE(<em>condition</em>); <br>
<em>condition</em> 为假</p>
<p>记住，当它们失败时，ASSERT_*产生一个致命失败并从当前函数返回，而EXCEPT_*产生一个非致命失败，允许函数继续运行。在两种情况下，一个断言失败都意味着它所包含的测试失败。</p>
<p>有效平台：Linux、Windows、Mac。</p>
<p><strong>二进制比较</strong></p>
<p>本节描述了比较两个值的一些断言。</p>
<p><strong>致命断言</strong><br>
<strong>非致命断言</strong><br>
<strong>验证条件</strong></p>
<p>ASSERT_EQ(<em>expected</em>, <em>actual</em>);<br>
EXPECT_EQ(<em>expected</em>, <em>actual</em>);<br>
<em>expected</em> == <em>actual</em></p>
<p>ASSERT_NE(<em>val1</em>, <em>val2</em>);<br>
EXPECT_NE(<em>val1</em>, <em>val2</em>);<br>
<em>val1</em> != <em>val2</em></p>
<p>ASSERT_LT(<em>val1</em>, <em>val2</em>);<br>
EXPECT_LT(<em>val1</em>, <em>val2</em>);<br>
<em>val1</em> &lt; <em>val2</em></p>
<p>ASSERT_LE(<em>val1</em>, <em>val2</em>);<br>
EXPECT_LE(<em>val1</em>, <em>val2</em>);<br>
<em>val1</em> &lt;= <em>val2</em></p>
<p>ASSERT_GT(<em>val1</em>, <em>val2</em>);<br>
EXPECT_GT(<em>val1</em>, <em>val2</em>);<br>
<em>val1</em> &gt; <em>val2</em></p>
<p>ASSERT_GE(<em>val1</em>, <em>val2</em>);<br>
EXPECT_GE(<em>val1</em>, <em>val2</em>);<br>
<em>val1</em> &gt;= <em>val2</em></p>
<p>在出现失败事件时，Google Test会将两个值（<em>Val1</em>和<em>Val2</em>）都打印出来。在ASSERT_EQ*和EXCEPT_EQ*断言（以及我们随后介绍类似的断言）中，你应该把你希望测试的表达式放在<em>actual</em>（实际值）的位置上，将其期望值放在<em>expected</em>（期望值）的位置上，因为Google Test的测试消息为这种惯例做了一些优化。</p>
<p>参数值必须是可通过断言的比较操作符进行比较的，否则你会得到一个编译错误。参数值还必须支持&lt;&lt;操作符来将值输入到ostream中。所有的C++内置类型都支持这一点。</p>
<p>这些断言可以用于用户自定义的型别，但你必须重载相应的比较操作符（如==、&lt;等）。如果定义有相应的操作符，推荐使用ASSERT_*()宏，因为它们不仅会输出比较的结果，还会输出两个比较对象。</p>
<p>参数表达式总是只被解析一次。因此，参数表达式有一定的副作用（side
effect，这里应该是指编译器不同，操作符解析顺序的不确定性）也是可以接受的。但是，同其他普通C/C++函数一样，参数表达式的解析顺序是不确定
的（如，一种编译器可以自由选择一种顺序来进行解析），而你的代码不应该依赖于某种特定的参数解析顺序。</p>
<p>ASSERT_EQ()对指针进行的是指针比较。即，如果被用在两个C字符串上，它会比较它们是否指向同样的内存地址，而不是它们所指向的字符串是
否有相同值。所以，如果你想对两个C字符串（例如，const
char*）进行值比较，请使用ASSERT_STREQ()宏，该宏会在后面介绍到。特别需要一提的是，要验证一个C字符串是否为空（NULL），使用
ASSERT_STREQ(NULL, c_string)。但是要比较两个string对象时，你应该使用ASSERT_EQ。</p>
<p>本节中介绍的宏都可以处理窄字符串对象和宽字符串对象（string和wstring）。</p>
<p>有效平台：Linux、Windows、Mac。</p>
<p><strong>字符串比较</strong></p>
<p>该组断言用于比较两个C字符串。如果你想要比较两个string对象，相应地使用EXPECT_EQ、EXPECT_NE等断言。</p>
<p><strong>致命断言</strong><br>
<strong>非致命断言</strong><br>
<strong>验证条件</strong></p>
<p>ASSERT_STREQ(<em>expected_str</em>, <em>actual_str</em>);<br>
EXPECT_STREQ(<em>expected_str</em>, <em>actual_str</em>);<br>
两个C字符串有相同的内容</p>
<p>ASSERT_STRNE(<em>str1</em>, <em>str2</em>);<br>
EXPECT_STRNE(<em>str1</em>, <em>str2</em>);<br>
两个C字符串有不同的内容</p>
<p>ASSERT_STRCASEEQ(<em>expected_str</em>, <em>actual_str</em>);<br>
EXPECT_STRCASEEQ(<em>expected_str</em>, <em>actual_str</em>);<br>
两个C字符串有相同的内容，忽略大小写</p>
<p>ASSERT_STRCASENE(<em>str1</em>, <em>str2</em>);<br>
EXPECT_STRCASENE(<em>str1</em>, <em>str2</em>);<br>
两个C字符串有不同的内容，忽略大小写</p>
<p>注意断言名称中出现的&#8220;CASE&#8221;意味着大小写被忽略了。</p>
<p>*STREQ*和*STRNE*也接受宽字符串（wchar_t*）。如果两个宽字符串比较失败，它们的值会做为UTF-8窄字符串被输出。</p>
<p>一个NULL空指针和一个空字符串会被认为是<em>不一样</em>的。</p>
<p>有效平台：Linux、Windows、Mac。</p>
<p>参见：更多的字符串比较的技巧（如子字符串、前缀和正则表达式匹配），请参见[Advanced Guide Advanced Google Test Guide]。</p>
<p><strong>简单的测试</strong></p>
<p>要创建一个测试：</p>
<ol>
    <li>使用TEST（）宏来定义和命名一个测试函数，它们是一些没有返回值的普通C++函数。</li>
    <li>在这个函数中，与你想要包含的其它任何有效C++代码一起，使用Google Test提供的各种断言来进行检查。</li>
    <li>测试的结果由其中的断言决定；如果测试中的任意断言失败（无论是致命还是非致命），或者测试崩溃，那么整个测试就失败了。否则，测试通过。 </li>
</ol>
<p>Cpp代码</p>
<ol>
    <li>TEST(test_case_name, test_name) { &nbsp;&nbsp;</li>
    <li>... test body ... &nbsp;&nbsp;</li>
    <li>}&nbsp;&nbsp;</li>
</ol>
<pre>TEST(test_case_name, test_name) {<br>... test body ...<br>}</pre>
<p>TEST（）的参数是从概括到特殊的。<em>第一个</em>参数是测试案例的名称，<em>第二个</em>参数是测试案例中的测试的名称。记住，一个测试案例可以包含任意数量的独立测试。一个测试的<em>全称</em>包括了包含它的测试案例名称，及其独立的名称。不同测试案例中的独立测试可以有相同的名称。</p>
<p>举例来说，让我们看一个简单的整数函数：</p>
<p>Cpp代码</p>
<ol>
    <li>int Factorial(int n); // 返回n的阶乘</li>
</ol>
<pre>int Factorial(int n); // 返回n的阶乘</pre>
<p>这个函数的测试案例应该看起来像是：</p>
<p>Cpp代码</p>
<ol>
    <li>// 测试0的阶乘</li>
    <li>TEST(FactorialTest, HandlesZeroInput) { &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; EXPECT_EQ(1, Factorial(0)); &nbsp;&nbsp;</li>
    <li>} &nbsp;&nbsp;</li>
    <li>// 测试正数的阶乘</li>
    <li>TEST(FactorialTest, HandlesPositiveInput) { &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; EXPECT_EQ(1, Factorial(1)); &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; EXPECT_EQ(2, Factorial(2)); &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; EXPECT_EQ(6, Factorial(3)); &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; EXPECT_EQ(40320, Factorial(8)); &nbsp;&nbsp;</li>
    <li>}&nbsp;&nbsp;</li>
</ol>
<pre>// 测试0的阶乘<br>TEST(FactorialTest, HandlesZeroInput) {<br>  EXPECT_EQ(1, Factorial(0));<br>}<br>// 测试正数的阶乘<br>TEST(FactorialTest, HandlesPositiveInput) {<br>  EXPECT_EQ(1, Factorial(1));<br>  EXPECT_EQ(2, Factorial(2));<br>  EXPECT_EQ(6, Factorial(3));<br>  EXPECT_EQ(40320, Factorial(8));<br>}</pre>
<p>Google
Test根据测试案例来分组收集测试结果，因此，逻辑相关的测试应该在同一测试案例中；换句话说，它们的TEST（）的第一个参数应该是一样的。在上面的
例子中，我们有两个测试，HandlesZeroInput和HandlesPostiveInput，它们都属于同一个测试案例
FactorialTest。</p>
<p>有效平台：Linux、Windows、Mac。</p>
<p><strong>测试固件（</strong><strong>Test Fixtures</strong><strong>，又做测试夹具、测试套件）：在多个测试中使用同样的数据配置</strong></p>
<p>当你发现自己编写了两个或多个测试来操作同样的数据，你可以采用一个<em>测试固件</em>。它让你可以在多个不同的测试中重用同样的对象配置。</p>
<p>要创建测试固件，只需：</p>
<ol>
    <li>创建一个类继承自testing::Test。将其中的成员声明为protected:或是public:，因为我们想要从子类中存取固件成员。</li>
    <li>在该类中声明你计划使用的任何对象。</li>
    <li>如果需要，编写一个默认构造函数或者SetUp()函数来为每个测试准备对象。常见错误包括将SetUp()拼写为Setup()（小写了u）——不要让它发生在你身上。</li>
    <li>如果需要，编写一个析构函数或者TearDown()函数来释放你在SetUp()函数中申请的资源。要知道什么时候应该使用构造函数/析构函数，什么时候又应该使用SetUp()/TearDown()函数，阅读我们的FAQ。</li>
    <li>如果需要，定义你的测试所需要共享的子程序。</li>
</ol>
<p>当我们要使用固件时，使用TEST_F()替换掉TEST()，它允许我们存取测试固件中的对象和子程序：</p>
<p>Cpp代码</p>
<ol>
    <li>TEST_F(test_case_name, test_name) { &nbsp;&nbsp;</li>
    <li>... test body ... &nbsp;&nbsp;</li>
    <li>}&nbsp;&nbsp;</li>
</ol>
<pre>TEST_F(test_case_name, test_name) {<br>... test body ...<br>}</pre>
<p>与TEST()一样，第一个参数是测试案例的名称，但对TEST_F()来说，这个名称必须与测试固件类的名称一些。你可能已经猜到了：_F正是指固件。</p>
<p>不幸地是，C++宏系统并不允许我们创建一个单独的宏来处理两种类型的测试。使用错误的宏会导致编译期的错误。</p>
<p>而且，你必须在TEST_F()中使用它之前，定义好这个测试固件类。否则，你会得到编译器的报错：&#8220;virtual outside class declaration&#8221;。</p>
<p>对于TEST_F()中定义的每个测试，Google Test将会：</p>
<ol>
    <li>在运行时创建一个<em>全新</em>的测试固件</li>
    <li>马上通过SetUp()初始化它，</li>
    <li>运行测试</li>
    <li>调用TearDown()来进行清理工作</li>
    <li>删除测试固件。注意，同一测试案例中，不同的测试拥有不同的测试固件。Google Test在创建下一个测试固件前总是会对现有固件进行删除。Google Test不会对多个测试重用一个测试固件。测试对测试固件的改动并不会影响到其他测试。</li>
</ol>
<p>例如，让我们为一个名为Queue的FIFO队列类编写测试，该类的接口如下：</p>
<p>Cpp代码</p>
<ol>
    <li>template &lt;typename E&gt; // E为元素类型</li>
    <li>class Queue { &nbsp;&nbsp;</li>
    <li>public: &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; Queue(); &nbsp;&nbsp;</li>
    <li>void Enqueue(const E&amp; element); &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; E* Dequeue(); // 返回 NULL 如果队列为空.</li>
    <li>size_t size() const; &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; ... &nbsp;&nbsp;</li>
    <li>};&nbsp;&nbsp;</li>
</ol>
<pre>template &lt;typename E&gt; // E为元素类型<br>class Queue {<br>public:<br>  Queue();<br>  void Enqueue(const E&amp; element);<br>  E* Dequeue(); // 返回 NULL 如果队列为空.<br>  size_t size() const;<br>  ...<br>};</pre>
<p>首先，定义一个固件类。习惯上，你应该把它的名字定义为FooTest，这里的Foo是被测试的类。</p>
<p>Cpp代码</p>
<ol>
    <li>class QueueTest : public testing::Test { &nbsp;&nbsp;</li>
    <li>protected: &nbsp;&nbsp;</li>
    <li>virtual void SetUp() { &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp; q1_.Enqueue(1); &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp; q2_.Enqueue(2); &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp; q2_.Enqueue(3); &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; } &nbsp;&nbsp;</li>
    <li>// virtual void TearDown() {}</li>
    <li>&nbsp;&nbsp; Queue&lt;int&gt; q0_; &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; Queue&lt;int&gt; q1_; &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; Queue&lt;int&gt; q2_; &nbsp;&nbsp;</li>
    <li>};&nbsp;&nbsp;</li>
</ol>
<pre>class QueueTest : public testing::Test {<br>protected:<br>  virtual void SetUp() {<br>    q1_.Enqueue(1);<br>    q2_.Enqueue(2);<br>    q2_.Enqueue(3);<br>  }<br>  // virtual void TearDown() {}<br>  Queue&lt;int&gt; q0_;<br>  Queue&lt;int&gt; q1_;<br>  Queue&lt;int&gt; q2_;<br>};</pre>
<p>在这个案例中，我们不需要TearDown()，因为每个测试后除了析构函数外不需要进行其它的清理工作了。</p>
<p>接下来我们使用TEST_F()和这个固件来编写测试。</p>
<p>Cpp代码</p>
<ol>
    <li>TEST_F(QueueTest, IsEmptyInitially) { &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; EXPECT_EQ(0, q0_.size()); &nbsp;&nbsp;</li>
    <li>} &nbsp;&nbsp;</li>
    <li>TEST_F(QueueTest, DequeueWorks) { &nbsp;&nbsp;</li>
    <li>int* n = q0_.Dequeue(); &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; EXPECT_EQ(NULL, n); &nbsp;&nbsp;</li>
    <li> <br></li>
    <li>&nbsp;&nbsp; n = q1_.Dequeue(); &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; ASSERT_TRUE(n != NULL); &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; EXPECT_EQ(1, *n); &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; EXPECT_EQ(0, q1_.size()); &nbsp;&nbsp;</li>
    <li>delete n; &nbsp;&nbsp;</li>
    <li> <br></li>
    <li>&nbsp;&nbsp; n = q2_.Dequeue(); &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; ASSERT_TRUE(n != NULL); &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; EXPECT_EQ(2, *n); &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; EXPECT_EQ(1, q2_.size()); &nbsp;&nbsp;</li>
    <li>delete n; &nbsp;&nbsp;</li>
    <li>}&nbsp;&nbsp;</li>
</ol>
<pre>TEST_F(QueueTest, IsEmptyInitially) {<br>  EXPECT_EQ(0, q0_.size());<br>}<br>TEST_F(QueueTest, DequeueWorks) {<br>  int* n = q0_.Dequeue();<br>  EXPECT_EQ(NULL, n);<br><br>  n = q1_.Dequeue();<br>  ASSERT_TRUE(n != NULL);<br>  EXPECT_EQ(1, *n);<br>  EXPECT_EQ(0, q1_.size());<br>  delete n;<br><br>  n = q2_.Dequeue();<br>  ASSERT_TRUE(n != NULL);<br>  EXPECT_EQ(2, *n);<br>  EXPECT_EQ(1, q2_.size());<br>  delete n;<br>}</pre>
<p>上面这段代码既使用了ASSERT_*断言，又使用了EXPECT_*断言。经验上讲，如果你想要断言失败后，测试能够继续进行以显示更多的错误
时，你应该使用EXPECT_*断言；使用ASSERT_*如果该断言失败后继续往下执行毫无意义。例如，Dequeue测试中的第二个断言是
ASSERT_TURE(n!= NULL)，因为我们随后会n指针解引用，如果n指针为空的话，会导致一个段错误。</p>
<p>当这些测试开始时，会发生如下情况：</p>
<ol>
    <li>Google Test创建一个QueueTest对象（我们把它叫做t1）。</li>
    <li>t1.SetUp()初始化t1。</li>
    <li>第一个测试（IsEmptyInitiallly）在t1上运行。</li>
    <li>测试完成后，t1.TearDown()进行一些清理工作。</li>
    <li>t1被析构。</li>
    <li>以上步骤在另一个QueueTest对象上重复进行，这回会运行DequeueWorks测试。</li>
</ol>
<p>有效平台：Linux、Windows、Mac。</p>
<p>注意：当一个测试对象被构造时，Google Test会自动地保存所有的Google Test变量标识，对象析构后进行恢复。</p>
<p><strong>调用测试</strong></p>
<p>TEST()和TEST_F()向Google Test隐式注册它们的测试。因此，与很多其他的C++测试框架不同，你不需要为了运行你定义的测试而将它们全部再列出来一次。</p>
<p>在定义好测试后，你可以通过RUN_ALL_TESTS()来运行它们，如果所有测试成功，该函数返回0，否则会返回1.注意RUN_ALL_TESTS()会运行你链接到的所有测试——它们可以来自不同的测试案例，甚至是来自不同的文件。</p>
<p>当被调用时，RUN_ALL_TESTS()宏会：</p>
<ol>
    <li>保存所有的Google Test标志。</li>
    <li>为一个侧测试创建测试固件对象。</li>
    <li>调用SetUp()初始化它。</li>
    <li>在固件对象上运行测试。</li>
    <li>调用TearDown()清理固件。</li>
    <li>删除固件。</li>
    <li>恢复所有Google Test标志的状态。</li>
    <li>重复上诉步骤，直到所有测试完成。</li>
</ol>
<p>此外，如果第二步时，测试固件的构造函数产生一个致命错误，继续执行3至5部显然没有必要，所以它们会被跳过。与之相似，如果第3部产生致命错误，第4部也会被跳过。</p>
<p>重要：你不能忽略掉RUN_ALL_TESTS()的返回值，否则gcc会报一个编译错误。这样设计的理由是自动化测试服务会根据测试退出返回码来
决定一个测试是否通过，而不是根据其stdout/stderr输出；因此你的main()函数必须返回RUN_ALL_TESTS()的值。</p>
<p>而且，你应该只调用RUN_ALL_TESTS()一次。多次调用该函数会与Google Test的一些高阶特性（如线程安全死亡测试thread-safe death tests）冲突，因而是不被支持的。</p>
<p>有效平台：Linux、Windows、Mac。</p>
<p><strong>编写</strong><strong>main()</strong><strong>函数</strong></p>
<p>你可以从下面这个样板开始:</p>
<p>Cpp代码</p>
<ol>
    <li>#include "this/package/foo.h"</li>
    <li>#include &lt;gtest/gtest.h&gt;</li>
    <li>namespace { &nbsp;&nbsp;</li>
    <li>// 测试Foo类的测试固件</li>
    <li>class FooTest : public testing::Test { &nbsp;&nbsp;</li>
    <li>protected: &nbsp;&nbsp;</li>
    <li>// You can remove any or all of the following functions if its body</li>
    <li>// is empty.</li>
    <li>&nbsp;&nbsp; FooTest() { &nbsp;&nbsp;</li>
    <li>// You can do set-up work for each test here.</li>
    <li>&nbsp;&nbsp; } &nbsp;&nbsp;</li>
    <li>virtual ~FooTest() { &nbsp;&nbsp;</li>
    <li>// You can do clean-up work that doesn't throw exceptions here.</li>
    <li>&nbsp;&nbsp; } &nbsp;&nbsp;</li>
    <li>// If the constructor and destructor are not enough for setting up</li>
    <li>// and cleaning up each test, you can define the following methods:</li>
    <li>virtual void SetUp() { &nbsp;&nbsp;</li>
    <li>// Code here will be called immediately after the constructor (right</li>
    <li>// before each test).</li>
    <li>&nbsp;&nbsp; } &nbsp;&nbsp;</li>
    <li>virtual void TearDown() { &nbsp;&nbsp;</li>
    <li>// Code here will be called immediately after each test (right</li>
    <li>// before the destructor).</li>
    <li>&nbsp;&nbsp; } &nbsp;&nbsp;</li>
    <li>// Objects declared here can be used by all tests in the test case for Foo.</li>
    <li>}; &nbsp;&nbsp;</li>
    <li> <br></li>
    <li>// Tests that the Foo::Bar() method does Abc.</li>
    <li>TEST_F(FooTest, MethodBarDoesAbc) { &nbsp;&nbsp;</li>
    <li>const string input_filepath = "this/package/testdata/myinputfile.dat"; &nbsp;&nbsp;</li>
    <li>const string output_filepath = "this/package/testdata/myoutputfile.dat"; &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; Foo f; &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp; EXPECT_EQ(0, f.Bar(input_filepath, output_filepath)); &nbsp;&nbsp;</li>
    <li>} &nbsp;&nbsp;</li>
    <li> <br></li>
    <li>// Tests that Foo does Xyz.</li>
    <li>TEST_F(FooTest, DoesXyz) { &nbsp;&nbsp;</li>
    <li>// Exercises the Xyz feature of Foo.</li>
    <li>} &nbsp;&nbsp;</li>
    <li>}&nbsp;&nbsp; // namespace</li>
    <li> <br></li>
    <li>int main(int argc, char **argv) { &nbsp;&nbsp;</li>
    <li>testing::InitGoogleTest(&amp;argc, argv); &nbsp;&nbsp;</li>
    <li>return RUN_ALL_TESTS(); &nbsp;&nbsp;</li>
    <li>}&nbsp;&nbsp;</li>
</ol>
<pre>#include "this/package/foo.h"<br>#include &lt;gtest/gtest.h&gt;<br>namespace {<br>// 测试Foo类的测试固件<br>class FooTest : public testing::Test {<br>protected:<br>  // You can remove any or all of the following functions if its body<br>  // is empty.<br>  FooTest() {<br>    // You can do set-up work for each test here.<br>  }<br>  virtual ~FooTest() {<br>    // You can do clean-up work that doesn't throw exceptions here.<br>  }<br>  // If the constructor and destructor are not enough for setting up<br>  // and cleaning up each test, you can define the following methods:<br>  virtual void SetUp() {<br>    // Code here will be called immediately after the constructor (right<br>    // before each test).<br>  }<br>  virtual void TearDown() {<br>    // Code here will be called immediately after each test (right<br>    // before the destructor).<br>  }<br>  // Objects declared here can be used by all tests in the test case for Foo.<br>};<br><br>// Tests that the Foo::Bar() method does Abc.<br>TEST_F(FooTest, MethodBarDoesAbc) {<br>  const string input_filepath = "this/package/testdata/myinputfile.dat";<br>  const string output_filepath = "this/package/testdata/myoutputfile.dat";<br>  Foo f;<br>  EXPECT_EQ(0, f.Bar(input_filepath, output_filepath));<br>}<br><br>// Tests that Foo does Xyz.<br>TEST_F(FooTest, DoesXyz) {<br>  // Exercises the Xyz feature of Foo.<br>}<br>}  // namespace<br><br>int main(int argc, char **argv) {<br>  testing::InitGoogleTest(&amp;argc, argv);<br>  return RUN_ALL_TESTS();<br>}</pre>
<p>testing::InitGoogleTest()函数负责解析命令行传入的Google
Test标志，并删除所有它可以处理的标志。这使得用户可以通过各种不同的标志控制一个测试程序的行为。关于这一点我们会在GTestAdvanced中
讲到。你必须在调用RUN_ALL_TESTS()之前调用该函数，否则就无法正确地初始化标示。</p>
<p>在Windows上InitGoogleTest()可以支持宽字符串，所以它也可以被用在以UNICODE模式编译的程序中。</p>
<p><strong>进阶阅读</strong></p>
<p>恭喜你！你已经学到了一些Google Test基础。你可以从编写和运行几个Google Test测试开始，再阅读一下<a  href="http://code.google.com/p/googletest/wiki/GoogleTestSamples"><font color="#669966">GoogleTestSamples</font></a>，或是继续研究<a  href="http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide"><font color="#669966">GoogleTestAdvancedGuide</font></a>，其中描述了很多更有用的Google Test特性。</p>
<p><strong>已知局限</strong></p>
<p>Google Test被设计为线程安全的。但是，我们还没有时间在各种平台上实现同步原语（synchronization
primitives）。因此，目前从两个线程同时使用Google
Test断言是不安全的。由于通常断言是在主线程中完成的，因此在大多数测试中这都不算问题。如果你愿意帮忙，你可以试着在gtest-port.h中实
现必要的同步原语。</p>
</div><img src ="http://www.cppblog.com/ngaut/aggbug/60514.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2008-08-31 20:19 <a href="http://www.cppblog.com/ngaut/archive/2008/08/31/60514.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Visual C++开发工具与调试技巧整理</title><link>http://www.cppblog.com/ngaut/archive/2008/07/26/57181.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Fri, 25 Jul 2008 17:19:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2008/07/26/57181.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/57181.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2008/07/26/57181.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/57181.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/57181.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/ngaut/archive/2008/07/26/57181.html'>阅读全文</a><img src ="http://www.cppblog.com/ngaut/aggbug/57181.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2008-07-26 01:19 <a href="http://www.cppblog.com/ngaut/archive/2008/07/26/57181.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Add color to your std::cout</title><link>http://www.cppblog.com/ngaut/archive/2008/07/14/56138.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Mon, 14 Jul 2008 15:03:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2008/07/14/56138.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/56138.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2008/07/14/56138.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/56138.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/56138.html</trackback:ping><description><![CDATA[<span id="intelliTXT">
<h2>Introduction</h2>
<p>This article illustrates a snippet that permits to add color to console messages.</p>
<h2>Background</h2>
<p>Well, does it really need any comments? </p>
<h2>Using the code</h2>
<p>This sample shows how to use the library:</p>
<pre><span class="code-preprocessor">#include</span><span class="code-preprocessor"> <span class="code-string">"</span><span class="code-string">ConsoleColor.h"</span><br></span><br><br>std::cout <span class="code-keyword">&lt;</span><span class="code-keyword">&lt;</span> green <span class="code-keyword">&lt;</span><span class="code-keyword">&lt;</span> <span class="code-string">"</span><span class="code-string">This text is written in green"</span> <br>          <span class="code-keyword">&lt;</span><span class="code-keyword">&lt;</span> white <span class="code-keyword">&lt;</span><span class="code-keyword">&lt;</span> std::endl;<br>std::cout <span class="code-keyword">&lt;</span><span class="code-keyword">&lt;</span> color(FOREGROUND_RED|FOREGROUND_GREEN) <br>          <span class="code-keyword">&lt;</span><span class="code-keyword">&lt;</span> <span class="code-string">"</span><span class="code-string">This text has a really exiting color !"</span> <br>          <span class="code-keyword">&lt;</span><span class="code-keyword">&lt;</span> white <span class="code-keyword">&lt;</span><span class="code-keyword">&lt;</span> std::endl;<br></pre>
<p>Now here is the "library":</p>
<div class="SmallText" id="premain1" style="width: 100%; cursor: pointer;"><img  src="http://www.codeproject.com/images/minus.gif" preid="1" id="preimg1" width="9" height="9"><span preid="1" style="margin-bottom: 0pt;" id="precollapse1"> Collapse</span></div>
<pre style="margin-top: 0pt;" id="pre1"><span class="code-comment">//</span><span class="code-comment"> ConsoleColor.h<br></span><br><br><span class="code-preprocessor">#pragma</span> once<br><span class="code-preprocessor">#include</span><span class="code-preprocessor"> <span class="code-keyword">&lt;</span><span class="code-leadattribute">iostream</span><span class="code-keyword">&gt;</span><br></span><br><span class="code-preprocessor">#include</span><span class="code-preprocessor"> <span class="code-keyword">&lt;</span><span class="code-leadattribute">windows.h</span><span class="code-keyword">&gt;</span><br></span><br><br><span class="code-keyword">inline</span> std::ostream&amp; blue(std::ostream &amp;s)<br>{<br>    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); <br>    SetConsoleTextAttribute(hStdout, FOREGROUND_BLUE<br>              |FOREGROUND_GREEN|FOREGROUND_INTENSITY);<br>    <span class="code-keyword">return</span> s;<br>}<br><br><span class="code-keyword">inline</span> std::ostream&amp; red(std::ostream &amp;s)<br>{<br>    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); <br>    SetConsoleTextAttribute(hStdout, <br>                FOREGROUND_RED|FOREGROUND_INTENSITY);<br>    <span class="code-keyword">return</span> s;<br>}<br><br><span class="code-keyword">inline</span> std::ostream&amp; green(std::ostream &amp;s)<br>{<br>    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); <br>    SetConsoleTextAttribute(hStdout, <br>              FOREGROUND_GREEN|FOREGROUND_INTENSITY);<br>    <span class="code-keyword">return</span> s;<br>}<br><br><span class="code-keyword">inline</span> std::ostream&amp; yellow(std::ostream &amp;s)<br>{<br>    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); <br>    SetConsoleTextAttribute(hStdout, <br>         FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY);<br>    <span class="code-keyword">return</span> s;<br>}<br><br><span class="code-keyword">inline</span> std::ostream&amp; white(std::ostream &amp;s)<br>{<br>    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); <br>    SetConsoleTextAttribute(hStdout, <br>       FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);<br>    <span class="code-keyword">return</span> s;<br>}<br><br><span class="code-keyword">struct</span> color {<br>    color(WORD attribute):m_color(attribute){};<br>    WORD m_color;<br>};<br><br><span class="code-keyword">template</span> <span class="code-keyword">&lt;</span><span class="code-keyword">class</span> _Elem, <span class="code-keyword">class</span> _Traits<span class="code-keyword">&gt;</span><br>std::basic_ostream<span class="code-keyword">&lt;</span>_Elem,_Traits<span class="code-keyword">&gt;</span>&amp; <br>      <span class="code-keyword">operator</span><span class="code-keyword">&lt;</span><span class="code-keyword">&lt;</span>(std::basic_ostream<span class="code-keyword">&lt;</span>_Elem,_Traits<span class="code-keyword">&gt;</span>&amp; i, color&amp; c)<br>{<br>    HANDLE hStdout=GetStdHandle(STD_OUTPUT_HANDLE); <br>    SetConsoleTextAttribute(hStdout,c.m_color);<br>    <span class="code-keyword">return</span> i;<br>}<br><br><span class="code-comment">//</span><span class="code-comment"> Copyleft Vincent Godin</span></pre>
</span><img src ="http://www.cppblog.com/ngaut/aggbug/56138.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2008-07-14 23:03 <a href="http://www.cppblog.com/ngaut/archive/2008/07/14/56138.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>asio终于随boost一起发布了</title><link>http://www.cppblog.com/ngaut/archive/2008/04/01/45940.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Tue, 01 Apr 2008 10:46:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2008/04/01/45940.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/45940.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2008/04/01/45940.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/45940.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/45940.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/ngaut/archive/2008/04/01/45940.html'>阅读全文</a><img src ="http://www.cppblog.com/ngaut/aggbug/45940.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2008-04-01 18:46 <a href="http://www.cppblog.com/ngaut/archive/2008/04/01/45940.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Huffman编码STL版--来自fxsjy的专栏 </title><link>http://www.cppblog.com/ngaut/archive/2007/12/30/40001.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Sun, 30 Dec 2007 05:55:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2007/12/30/40001.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/40001.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2007/12/30/40001.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/40001.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/40001.html</trackback:ping><description><![CDATA[<font color=#002c99>Huffman编码STL版</font>&nbsp;&nbsp;
<script src="http://blog.csdn.net/count.aspx?ID=1395927&amp;Type=Rank"></script>
<span title=文章指数:80><img src="http://blog.csdn.net/images/star.gif" border=0><img src="http://blog.csdn.net/images/star.gif" border=0><img src="http://blog.csdn.net/images/star.gif" border=0><img src="http://blog.csdn.net/images/star.gif" border=0></span>&nbsp;&nbsp;<img title="CSDN Blog推出文章指数概念，文章指数是对Blog文章综合评分后推算出的，综合评分项分别是该文章的点击量，回复次数，被网摘收录数量，文章长度和文章类型；满分100，每月更新一次。" alt="CSDN Blog推出文章指数概念，文章指数是对Blog文章综合评分后推算出的，综合评分项分别是该文章的点击量，回复次数，被网摘收录数量，文章长度和文章类型；满分100，每月更新一次。" src="http://blog.csdn.net/images/ask.gif" border=0>
<div class=postText>
<div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 95%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<div><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">algorithm</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">vector</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">functional</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;std;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;TreeNode<br><img id=_119_243_Open_Image onclick="this.style.display='none'; document.getElementById('_119_243_Open_Text').style.display='none'; document.getElementById('_119_243_Closed_Image').style.display='inline'; document.getElementById('_119_243_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=_119_243_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_119_243_Closed_Text').style.display='none'; document.getElementById('_119_243_Open_Image').style.display='inline'; document.getElementById('_119_243_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=_119_243_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</span><span id=_119_243_Open_Text><span style="COLOR: #000000">{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;Weight;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">权值</span><span style="COLOR: #008000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;flag;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">代表符号如a,b,c，如果为非叶子节点flag=='-'</span><span style="COLOR: #008000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;TreeNode</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;left;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">左子树</span><span style="COLOR: #008000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;TreeNode</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;right;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">右子树</span><span style="COLOR: #008000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align=top></span><span style="COLOR: #000000">}</span></span><span style="COLOR: #000000">;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><br><img id=_247_257_Open_Image onclick="this.style.display='none'; document.getElementById('_247_257_Open_Text').style.display='none'; document.getElementById('_247_257_Closed_Image').style.display='inline'; document.getElementById('_247_257_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=_247_257_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_247_257_Closed_Text').style.display='none'; document.getElementById('_247_257_Open_Image').style.display='inline'; document.getElementById('_247_257_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=_247_257_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id=_247_257_Open_Text><span style="COLOR: #808080">///</span><span style="COLOR: #008000">全局变量</span><span style="COLOR: #808080">///</span></span><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">vector</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;g_Path;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">路径栈</span><span style="COLOR: #008000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">vector</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">TreeNode</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;g_Heap;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">用于构造树的堆</span><span style="COLOR: #008000"><br><img id=_320_333_Open_Image onclick="this.style.display='none'; document.getElementById('_320_333_Open_Text').style.display='none'; document.getElementById('_320_333_Closed_Image').style.display='inline'; document.getElementById('_320_333_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=_320_333_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_320_333_Closed_Text').style.display='none'; document.getElementById('_320_333_Open_Image').style.display='inline'; document.getElementById('_320_333_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=_320_333_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id=_320_333_Open_Text><span style="COLOR: #808080">////////////</span><span style="COLOR: #008000">/</span><span style="COLOR: #808080"></span></span><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;UDGreater(TreeNode&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">a,TreeNode&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">b)<br><img id=_376_479_Open_Image onclick="this.style.display='none'; document.getElementById('_376_479_Open_Text').style.display='none'; document.getElementById('_376_479_Closed_Image').style.display='inline'; document.getElementById('_376_479_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=_376_479_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_376_479_Closed_Text').style.display='none'; document.getElementById('_376_479_Open_Image').style.display='inline'; document.getElementById('_376_479_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=_376_479_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</span><span id=_376_479_Open_Text><span style="COLOR: #000000">{&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">为TreeNode定义一种比较大小的函数，以便后面构造小根堆</span><span style="COLOR: #008000"><br><img id=_433_451_Open_Image onclick="this.style.display='none'; document.getElementById('_433_451_Open_Text').style.display='none'; document.getElementById('_433_451_Closed_Image').style.display='inline'; document.getElementById('_433_451_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=_433_451_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_433_451_Closed_Text').style.display='none'; document.getElementById('_433_451_Open_Image').style.display='inline'; document.getElementById('_433_451_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(a.Weight</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">b.Weight)</span><span id=_433_451_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</span><span id=_433_451_Open_Text><span style="COLOR: #000000">{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img id=_458_477_Open_Image onclick="this.style.display='none'; document.getElementById('_458_477_Open_Text').style.display='none'; document.getElementById('_458_477_Closed_Image').style.display='inline'; document.getElementById('_458_477_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=_458_477_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_458_477_Closed_Text').style.display='none'; document.getElementById('_458_477_Open_Image').style.display='inline'; document.getElementById('_458_477_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span id=_458_477_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</span><span id=_458_477_Open_Text><span style="COLOR: #000000">{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;printPath()<br><img id=_499_621_Open_Image onclick="this.style.display='none'; document.getElementById('_499_621_Open_Text').style.display='none'; document.getElementById('_499_621_Closed_Image').style.display='inline'; document.getElementById('_499_621_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=_499_621_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_499_621_Closed_Text').style.display='none'; document.getElementById('_499_621_Open_Image').style.display='inline'; document.getElementById('_499_621_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=_499_621_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</span><span id=_499_621_Open_Text><span style="COLOR: #000000">{</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">打印从根节点到当前叶子节点的路径，即huffman编码</span><span style="COLOR: #008000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;vector</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">::iterator&nbsp;it;<br><img id=_603_619_Open_Image onclick="this.style.display='none'; document.getElementById('_603_619_Open_Text').style.display='none'; document.getElementById('_603_619_Closed_Image').style.display='inline'; document.getElementById('_603_619_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=_603_619_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_603_619_Closed_Text').style.display='none'; document.getElementById('_603_619_Open_Image').style.display='inline'; document.getElementById('_603_619_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(it</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">g_Path.begin();it</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">g_Path.end();it</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)</span><span id=_603_619_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</span><span id=_603_619_Open_Text><span style="COLOR: #000000">{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="COLOR: #000000">&lt;&lt;*</span><span style="COLOR: #000000">it;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;CreateHuffmanTree()<br><img id=_649_1266_Open_Image onclick="this.style.display='none'; document.getElementById('_649_1266_Open_Text').style.display='none'; document.getElementById('_649_1266_Closed_Image').style.display='inline'; document.getElementById('_649_1266_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=_649_1266_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_649_1266_Closed_Text').style.display='none'; document.getElementById('_649_1266_Open_Image').style.display='inline'; document.getElementById('_649_1266_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=_649_1266_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</span><span id=_649_1266_Open_Text><span style="COLOR: #000000">{</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">构造Huffman树</span><span style="COLOR: #008000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;TreeNode&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">left,</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">right,parent;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;make_heap(g_Heap.begin(),g_Heap.end(),UDGreater);</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">构造小根堆</span><span style="COLOR: #008000"><br><img id=_775_1264_Open_Image onclick="this.style.display='none'; document.getElementById('_775_1264_Open_Text').style.display='none'; document.getElementById('_775_1264_Closed_Image').style.display='inline'; document.getElementById('_775_1264_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=_775_1264_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_775_1264_Closed_Text').style.display='none'; document.getElementById('_775_1264_Open_Image').style.display='inline'; document.getElementById('_775_1264_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(g_Heap.size()</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)</span><span id=_775_1264_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</span><span id=_775_1264_Open_Text><span style="COLOR: #000000">{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;left</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;TreeNode();<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;right</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;TreeNode();<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pop_heap(g_Heap.begin(),g_Heap.end(),UDGreater);<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">left</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">g_Heap.back();&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">取出最小的节点</span><span style="COLOR: #008000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_Heap.pop_back();<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pop_heap(g_Heap.begin(),g_Heap.end(),UDGreater);<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">right</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">g_Heap.back();&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">取出第二小的节点</span><span style="COLOR: #008000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_Heap.pop_back();<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parent.left</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">left;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">根据这两个节点生成一个新的节点</span><span style="COLOR: #008000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parent.right</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">right;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parent.Weight</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">left</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">Weight</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">right</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">Weight;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parent.flag</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_Heap.push_back(parent);<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push_heap(g_Heap.begin(),g_Heap.end(),UDGreater);</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">在堆中添加进去新生成的节点&nbsp;</span><span style="COLOR: #008000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;TravelHuffmanTree(TreeNode&nbsp;parent)<br><img id=_1309_1660_Open_Image onclick="this.style.display='none'; document.getElementById('_1309_1660_Open_Text').style.display='none'; document.getElementById('_1309_1660_Closed_Image').style.display='inline'; document.getElementById('_1309_1660_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=_1309_1660_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_1309_1660_Closed_Text').style.display='none'; document.getElementById('_1309_1660_Open_Image').style.display='inline'; document.getElementById('_1309_1660_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=_1309_1660_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</span><span id=_1309_1660_Open_Text><span style="COLOR: #000000">{</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">遍历huffman树，在此过程中输出叶节点的编码</span><span style="COLOR: #008000"><br><img id=_1381_1468_Open_Image onclick="this.style.display='none'; document.getElementById('_1381_1468_Open_Text').style.display='none'; document.getElementById('_1381_1468_Closed_Image').style.display='inline'; document.getElementById('_1381_1468_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=_1381_1468_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_1381_1468_Closed_Text').style.display='none'; document.getElementById('_1381_1468_Open_Image').style.display='inline'; document.getElementById('_1381_1468_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(parent.left</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">NULL&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">&nbsp;parent.right</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">NULL)</span><span id=_1381_1468_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</span><span id=_1381_1468_Open_Text><span style="COLOR: #000000">{</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">如果是叶子节点</span><span style="COLOR: #008000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">parent.flag</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printPath();&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">打印路径即huffman编码</span><span style="COLOR: #008000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">endl;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img id=_1475_1658_Open_Image onclick="this.style.display='none'; document.getElementById('_1475_1658_Open_Text').style.display='none'; document.getElementById('_1475_1658_Closed_Image').style.display='inline'; document.getElementById('_1475_1658_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=_1475_1658_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_1475_1658_Closed_Text').style.display='none'; document.getElementById('_1475_1658_Open_Image').style.display='inline'; document.getElementById('_1475_1658_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span id=_1475_1658_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</span><span id=_1475_1658_Open_Text><span style="COLOR: #000000">{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_Path.push_back(</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">);&nbsp;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TravelHuffmanTree(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">parent.left);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">遍历左子树</span><span style="COLOR: #008000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_Path.pop_back();<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_Path.push_back(</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">);<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TravelHuffmanTree(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">parent.right);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">遍历右子树</span><span style="COLOR: #008000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_Path.pop_back();<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align=top><br><img id=_1673_2009_Open_Image onclick="this.style.display='none'; document.getElementById('_1673_2009_Open_Text').style.display='none'; document.getElementById('_1673_2009_Closed_Image').style.display='inline'; document.getElementById('_1673_2009_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=_1673_2009_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_1673_2009_Closed_Text').style.display='none'; document.getElementById('_1673_2009_Open_Image').style.display='inline'; document.getElementById('_1673_2009_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align=top></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main()</span><span id=_1673_2009_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</span><span id=_1673_2009_Open_Text><span style="COLOR: #000000">{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;count</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;TreeNode&nbsp;temp;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">请输入字符的个数</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">endl;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;cin</span><span style="COLOR: #000000">&gt;&gt;</span><span style="COLOR: #000000">count;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">请输入要编码的字符和它的权值，用空格隔开，如：a&nbsp;12.5</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">endl;<br><img id=_1804_1901_Open_Image onclick="this.style.display='none'; document.getElementById('_1804_1901_Open_Text').style.display='none'; document.getElementById('_1804_1901_Closed_Image').style.display='inline'; document.getElementById('_1804_1901_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=_1804_1901_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_1804_1901_Closed_Text').style.display='none'; document.getElementById('_1804_1901_Open_Image').style.display='inline'; document.getElementById('_1804_1901_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(count</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">)</span><span id=_1804_1901_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</span><span id=_1804_1901_Open_Text><span style="COLOR: #000000">{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cin</span><span style="COLOR: #000000">&gt;&gt;</span><span style="COLOR: #000000">temp.flag</span><span style="COLOR: #000000">&gt;&gt;</span><span style="COLOR: #000000">temp.Weight;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp.left</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">NULL;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp.right</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">NULL;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_Heap.push_back(temp);<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;CreateHuffmanTree();&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">创建huffman树</span><span style="COLOR: #008000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;TreeNode&nbsp;root</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">g_Heap.front();<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;TravelHuffmanTree(root);&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">遍历huffman树</span><span style="COLOR: #008000"><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align=top></span><span style="COLOR: #000000">}</span></span></div>
</div>
&nbsp;<br></div>
<img src ="http://www.cppblog.com/ngaut/aggbug/40001.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2007-12-30 13:55 <a href="http://www.cppblog.com/ngaut/archive/2007/12/30/40001.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>asio作者写的好东东,不容错过哦</title><link>http://www.cppblog.com/ngaut/archive/2007/12/28/39863.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Fri, 28 Dec 2007 12:43:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2007/12/28/39863.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/39863.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2007/12/28/39863.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/39863.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/39863.html</trackback:ping><description><![CDATA[<h2 class=date-header>Wednesday, August 08, 2007</h2>
<div class="post hentry uncustomized-post-template"><a name=9091214669274461484></a>
<h3 class="post-title entry-title"><a href="http://think-async.blogspot.com/2007/08/time-travel.html"><u><font color=#0000ff>Time Travel</font></u></a> </h3>
<div class=post-header-line-1></div>
<div class="post-body entry-content">
<p>Many event-driven programs involve state changes that are triggered according to the system clock. You might be coding for:
<ul><br>
    <li>A share market that opens at 10:00am and closes at 4:00pm.<br>
    <li>An off-peak phone billing rate that starts after 7:00pm.<br>
    <li>An interest calculation that is run on the last day of every month.<br></li>
</ul>
The <code>asio::deadline_timer</code> class lets you handle this easily. For example:<br>
<pre>using namespace boost::posix_time;<br>typedef boost::date_time::c_local_adjustor&lt;ptime&gt; local_adj;<br><br>...<br><br>asio::deadline_timer timer(io_service);<br><br>ptime open_time(second_clock::local_time().date(), hours(10));<br>timer.expires_at(local_adj::local_to_utc(open_time));<br>timer.async_wait(open_market);<br></pre>
There's a catch: to test that your timer events work correctly, you have to run your program at the right time of day. It usually isn't practical to sit around all day (or, worse, all year) waiting for the timers to expire.<br><br>
<h3>Time Traits</h3>
<br>You may have noticed that the <code>asio::deadline_timer</code> class is actually a typedef:<br>
<pre>typedef basic_deadline_timer&lt;boost::posix_time::ptime&gt;<br>  deadline_timer;</pre>
where the basic_deadline_timer class template is declared as follows:<br>
<pre>template &lt;<br>    typename Time,<br>    typename TimeTraits<br>      = asio::time_traits&lt;Time&gt;,<br>    typename TimerService<br>      = deadline_timer_service&lt;Time, TimeTraits&gt; &gt;<br>class basic_deadline_timer;<br></pre>
In the context of our problem, the most interesting template parameter is the second one: <code>TimeTraits</code>. An implementation of <code>TimeTraits</code> lets us customise the treatment of the template's <code>Time</code> parameter, and consequently the behaviour of the timer itself.<br><br>A <code>TimeTraits</code> class must implement an interface that matches the following:<br>
<pre>class TimeTraits<br>{<br>public:<br>  // The type used to represent an absolute time, i.e. the same<br>  // as the Time template parameter to basic_deadline_timer.<br>  typedef ... time_type;<br><br>  // The type used to represent the difference between two<br>  // absolute times.<br>  typedef ... duration_type;<br><br>  // Returns the current time.<br>  static time_type now();<br><br>  // Returns a new absolute time resulting from adding the<br>  // duration d to the absolute time t.<br>  static time_type add(time_type t, duration_type d);<br><br>  // Returns the duration resulting from subtracting t2 from t1.<br>  static duration_type subtract(time_type t1, time_type t2);<br><br>  // Returns whether t1 is to be treated as less than t2.<br>  static bool less_than(time_type t1, time_type t2);<br><br>  // Returns a "posix" duration corresponding to the duration d.<br>  static boost::posix_time::time_duration to_posix_duration(<br>      duration_type d);<br>};</pre>
As you can see from the declaration of the <code>basic_deadline_timer</code> class template, Asio provides a default <code>TimeTraits</code> implementation called <code>asio::time_traits&lt;&gt;</code>.<br><br>
<h3>Offsetting Now</h3>
<br>To test our timer events at any time of our choosing, we simply need to change the definition of "now" using a custom <code>TimeTraits</code> class.<br><br>Since we want to use the same time types as the regular <code>deadline_timer</code> class, we'll start by reusing the default traits implementation:<br>
<pre>class offset_time_traits<br>  : public asio::deadline_timer::traits_type<br>{<br>};</pre>
The value returned by the <code>now()</code> function will be offset from the system clock by a specified duration:<br>
<pre>class offset_time_traits<br>  : public asio::deadline_timer::traits_type<br>{<br><br>private:<br>  <font color=red>static duration_type offset_;</font><br>};</pre>
which is simply added to the system clock:<br>
<pre>class offset_time_traits<br>  : public asio::deadline_timer::traits_type<br>{<br>public:<br>  <font color=red>static time_type now()<br>  {<br>    return add(asio::deadline_timer::traits_type::now(), offset_);<br>  }</font><br><br>private:<br>  static duration_type offset_;<br>};</pre>
Of course, we will also need to provide a way to set the offset, which can be done by setting an initial value for "now":<br>
<pre>class offset_time_traits<br>  : public asio::deadline_timer::traits_type<br>{<br>public:<br>  static time_type now()<br>  {<br>    return add(asio::deadline_timer::traits_type::now(), offset_);<br>  }<br><br>  <font color=red>static void set_now(time_type t)<br>  {<br>    offset_ =<br>      subtract(t, asio::deadline_timer::traits_type::now());<br>  }</font><br><br>private:<br>  static duration_type offset_;<br>};</pre>
<br>
<h3>Creating a Timer</h3>
<br>To use our custom traits type with the <code>basic_deadline_timer</code> template, we simply need to add the following typedef:<br>
<pre>typedef asio::basic_deadline_timer&lt;<br>    boost::posix_time::ptime, offset_time_traits&gt; offset_timer;</pre>
To see the offset timer in action, let's create a timer to fire precisely at the start of the coming new year. So we don't have to wait until then, we'll set "now" to be just ten seconds prior to midnight:<br>
<pre>offset_time_traits::set_now(<br>    boost::posix_time::from_iso_string("20071231T235950"));<br><br>offset_timer timer(io_service);<br>timer.expires_at(<br>    boost::posix_time::from_iso_string("20080101T000000"));<br>timer.async_wait(handle_timeout);<br><br>io_service.run();</pre>
When the program is run, it will take just ten seconds to complete.<br><br>
<h3>Jumping Through Time</h3>
<br>One feature not supported by the above solution is the ability to change the definition of "now" after the timers have been started. However, if your timer events are spread across a long period of time, then this is likely to be something you would want.<br><br>Let's say that the next timer does not expire for several hours, but in an attempt to speed things up we call <code>set_now()</code> to move to just seconds before. The problem with the above traits class is that the existing asynchronous wait operation does not know about the change to "now", and so will continue to run for the remaining hours.<br><br>Fortunately, Asio provides a way around this: by customising the <code>to_posix_duration()</code> function in our traits class.<br><br>The <code>to_posix_duration()</code> function is normally used to convert from a user-defined duration type to a type that Asio knows about (namely <code>boost::posix_time::time_duration</code>). The key point here is that this converted duration value is used by Asio to determine how long to wait until the timer expires. Furthermore, it doesn't matter if this function returns a duration that is smaller (even substantially so) than the actual duration. The timer won't fire early, because Asio guarantees that it won't expire until the following condition holds true:<br>
<pre>!TimeTraits::less_than(Time_Traits::now(), timer.expires_at())</pre>
So, by adding the <code>to_posix_duration()</code> function to our traits class:<br>
<pre>class offset_time_traits<br>  : public asio::deadline_timer::traits_type<br>{<br>public:<br>  static time_type now()<br>  {<br>    return add(asio::deadline_timer::traits_type::now(), offset_);<br>  }<br><br>  static void set_now(time_type t)<br>  {<br>    offset_ =<br>      subtract(t, asio::deadline_timer::traits_type::now());<br>  }<br><br>  <font color=red>static boost::posix_time::time_duration to_posix_duration(<br>      duration_type d)<br>  {<br>    return d &lt; boost::posix_time::seconds(5)<br>      ? d : boost::posix_time::seconds(5);<br>  }</font><br><br>private:<br>  static duration_type offset_;<br>};</pre>
we can ensure that Asio detects changes to the offset within seconds.
<p>&#160;</p>
<div style="CLEAR: both"></div>
</div>
<div class=post-footer>
<p class="post-footer-line post-footer-line-1"><span class="post-author vcard">Posted by <span class=fn>chris</span> </span><span class=post-timestamp>at <a class=timestamp-link title="permanent link" href="http://think-async.blogspot.com/2007/08/time-travel.html" rel=bookmark><abbr class=published title=2007-08-08T23:00:00+10:00><u><font color=#0000ff>11:00 PM</abbr></font></u></a> </span><span class=post-comment-link><a class=comment-link onclick="" href="http://www.blogger.com/comment.g?blogID=35024958&amp;postID=9091214669274461484"><u><font color=#0000ff>1 comments</font></u></a> </span><span class="post-backlinks post-comment-link"></span><span class=post-icons><span class="item-control blog-admin pid-660467121"><a title="Edit Post" href="http://www.blogger.com/post-edit.g?blogID=35024958&amp;postID=9091214669274461484"><u><font color=#0000ff><span class=quick-edit-icon>&nbsp;</span> </font></u></a></span></span></p>
<p class="post-footer-line post-footer-line-2"><span class=post-labels>Labels: <a href="http://think-async.blogspot.com/search/label/asio" rel=tag><u><font color=#0000ff>asio</font></u></a>, <a href="http://think-async.blogspot.com/search/label/boost" rel=tag><u><font color=#0000ff>boost</font></u></a>, <a href="http://think-async.blogspot.com/search/label/timer" rel=tag><u><font color=#0000ff>timer</font></u></a> </span></p>
<p class="post-footer-line post-footer-line-3"></p>
</div>
</div>
<h2 class=date-header>Thursday, April 26, 2007</h2>
<div class="post hentry uncustomized-post-template"><a name=7236229129837214596></a>
<h3 class="post-title entry-title"><a href="http://think-async.blogspot.com/2007/04/new-home-heating-solution.html"><u><font color=#0000ff>New home heating solution</font></u></a> </h3>
<div class=post-header-line-1></div>
<div class="post-body entry-content">
<p>For quite some time I have wanted to take a really good look at improving Boost.Asio's scalability across multiple processors. Unfortunately, getting unlimited access to this sort of hardware has been somewhat problematic. What I really needed was a decent multiprocessor box at home :)<br><br>The arrival of Intel's Clovertown quad core CPUs gave me the opportunity. The primary goal was to maximise parallelism while minimising the cost, and the lowest spec quad cores were cheap enough for me to justify spending the money. So, after months of <strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">thinking</strong> (and weeks of waiting for parts), last week I finally completed my home-built server.<br><br>Here are the headline specs:
<ul><br>
    <li>Two Intel Xeon E5310 quad core processors (1.6 GHz)<br><br>
    <li>Tyan Tempest i5000XL motherboard<br><br>
    <li>2GB DDR2-667 fully buffered ECC DIMMs<br><br>
    <li>OCZ GameXStream 700W power supply (OK, OK, it's a little overpowered, but it was in stock!)<br><br>
    <li>Other stuff like case, hard disk, DVD drive, video card and wireless LAN card<br><br>
    <li>Lots of fans to provide soothing ambient noise<br><br></li>
</ul>
So far I have installed CentOS Linux 5 on it, but also plan to try Solaris 10 and FreeBSD. It seems pretty snappy.
<p>&#160;</p>
<div style="CLEAR: both"></div>
</div>
<div class=post-footer>
<p class="post-footer-line post-footer-line-1"><span class="post-author vcard">Posted by <span class=fn>chris</span> </span><span class=post-timestamp>at <a class=timestamp-link title="permanent link" href="http://think-async.blogspot.com/2007/04/new-home-heating-solution.html" rel=bookmark><abbr class=published title=2007-04-26T23:57:00+10:00><u><font color=#0000ff>11:57 PM</abbr></font></u></a> </span><span class=post-comment-link><a class=comment-link onclick="" href="http://www.blogger.com/comment.g?blogID=35024958&amp;postID=7236229129837214596"><u><font color=#0000ff>2 comments</font></u></a> </span><span class="post-backlinks post-comment-link"></span><span class=post-icons><span class="item-control blog-admin pid-660467121"><a title="Edit Post" href="http://www.blogger.com/post-edit.g?blogID=35024958&amp;postID=7236229129837214596"><u><font color=#0000ff><span class=quick-edit-icon>&nbsp;</span> </font></u></a></span></span></p>
<p class="post-footer-line post-footer-line-2"><span class=post-labels>Labels: <a href="http://think-async.blogspot.com/search/label/asio" rel=tag><u><font color=#0000ff>asio</font></u></a>, <a href="http://think-async.blogspot.com/search/label/boost" rel=tag><u><font color=#0000ff>boost</font></u></a>, <a href="http://think-async.blogspot.com/search/label/hardware" rel=tag><u><font color=#0000ff>hardware</font></u></a> </span></p>
<p class="post-footer-line post-footer-line-3"></p>
</div>
</div>
<h2 class=date-header>Monday, January 15, 2007</h2>
<div class="post hentry uncustomized-post-template"><a name=993190014642551346></a>
<h3 class="post-title entry-title"><a href="http://think-async.blogspot.com/2007/01/unbuffered-socket-iostreams.html"><u><font color=#0000ff>Unbuffered socket iostreams</font></u></a> </h3>
<div class=post-header-line-1></div>
<div class="post-body entry-content">
<p>Boost.Asio includes an iostreams-based interface to TCP sockets, <code>ip::tcp::iostream</code>, for simple use cases. However, like the file iostreams provided by the standard library, <code>ip::tcp::iostream</code> buffers input and output data. This can lead to problems if you forget to explicitly flush the stream. For example, consider the following code to perform an HTTP request:<br>
<pre>ip::tcp::iostream stream("www.boost.org", "http");<br>stream &lt;&lt; "GET / HTTP/1.0\r\n"<br>       &lt;&lt; "Host: www.boost.org\r\n"<br>       &lt;&lt; "\r\n";<br><br>std::string response_line;<br>std::getline(stream, response_line);<br>...</pre>
The code will be stuck on the <code>getline()</code> call waiting for the response, because the request will still be sitting <code>stream</code>'s output buffer. The correct code looks like this:<br>
<pre>ip::tcp::iostream stream("www.boost.org", "http");<br>stream &lt;&lt; "GET / HTTP/1.0\r\n"<br>       &lt;&lt; "Host: www.boost.org\r\n"<br>       &lt;&lt; "\r\n"<br>       <font color=red>&lt;&lt; std::flush</font>;</pre>
The <code>std::flush</code> will cause the stream to send the entire contents of its output buffer at that point.<br><br>Boost.Asio now supports an alternative solution: turn off the stream's output buffering. This is accomplished as follows:<br>
<pre>ip::tcp::iostream stream("www.boost.org", "http");<br><font color=red>stream.rdbuf()-&gt;pubsetbuf(0, 0);</font><br>stream &lt;&lt; "GET / HTTP/1.0\r\n"<br>       &lt;&lt; "Host: www.boost.org\r\n"<br>       &lt;&lt; "\r\n";</pre>
Now you can send and receive to your heart's content, without having to worry about whether your message is stuck in the output buffer, but be warned: an unbuffered stream is a lot less efficient in terms of system calls. Don't use this feature if you care about performance.</div>
</div>
<img src ="http://www.cppblog.com/ngaut/aggbug/39863.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2007-12-28 20:43 <a href="http://www.cppblog.com/ngaut/archive/2007/12/28/39863.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个简单的递归下降分析表达式的例子</title><link>http://www.cppblog.com/ngaut/archive/2007/12/25/39612.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Tue, 25 Dec 2007 11:36:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2007/12/25/39612.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/39612.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2007/12/25/39612.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/39612.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/39612.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 好友学习递归时无法理解用递归下降的方式分析表达式，所以写了个简单的例子，为了使代码尽可能简单，省略了此法分析模块，直接使用人脑分析的词法^_^由于好友不懂c++，所以这里虽然用的c++，但还是按照c的方式写的代码。#include&nbsp;&lt;vector&gt;#include&nbsp;&lt;iostream&gt;#include&nbsp;&lt;assert.h&gt;usi...&nbsp;&nbsp;<a href='http://www.cppblog.com/ngaut/archive/2007/12/25/39612.html'>阅读全文</a><img src ="http://www.cppblog.com/ngaut/aggbug/39612.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2007-12-25 19:36 <a href="http://www.cppblog.com/ngaut/archive/2007/12/25/39612.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>编译boost库-用vc2005编译boost1.34.1 </title><link>http://www.cppblog.com/ngaut/archive/2007/11/19/36968.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Mon, 19 Nov 2007 13:08:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2007/11/19/36968.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/36968.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2007/11/19/36968.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/36968.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/36968.html</trackback:ping><description><![CDATA[<br>
<script>function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>
<div class="postTitle">&nbsp;&nbsp; 编译boost库-用vc2005编译boost1.34.1&nbsp;	</div>
//打开控制台窗口，请使用vs2005在开始菜单中的&#8220;Visual Studio Tools-&gt;Visual Studio 2005 命令提示&#8221;打开控制台，这样vc的的编译环境就设置好了。<br>//假设boost安装包的解压的目录为{BOOST_SRC}中。<br>//先编译出bjam.exe，它被用于安装boost库<br>cd {BOOST_SRC}\tools\build\jam_src<br>build.bat<br>//利用编译出的bjam.exe程序编译并安装boost库<br>cd {BOOST_SRC}<br>copy {BOOST_SRC}\tools\build\jam_src\bin.ntx86\bjam.exe<br>//下面的命令的各选项的说明：<br>//prefix&nbsp;&nbsp;&nbsp; 将boost安装到的路径（生成的头文件和库文件都会放到该路径中）。<br>//重定义以下变量（利用-s设置）：<br>//VC80_ROOT　　vc2005的安装路径，如果未将vc2005安装到默认位置，你必须指定该项。<br>//TOOLS&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;使用的编译工具，vc2005对应的是vc-8_0<br>//PYTHON_ROOT&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; python的安装目录，如果未将BOOST安装到默认位置，你必须指定该项。<br>//BUILD&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;编译结果选项，默认会生成尽可能多的版本，如调试版／发行版，静态库／动态库，单线程／多线程。<br>bjam
"-sVC80_ROOT=D:\Program Files\Microsoft Visual Studio 8\VC"
"-sTOOLS=vc-8_0"&nbsp; "-sPYTHON_ROOT=D:\Program Files\Python24"
"--prefix=E:\librarys\boost" install <br><img src ="http://www.cppblog.com/ngaut/aggbug/36968.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2007-11-19 21:08 <a href="http://www.cppblog.com/ngaut/archive/2007/11/19/36968.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何解决"找不到MSVCR80.dll "的问题</title><link>http://www.cppblog.com/ngaut/archive/2007/11/17/36786.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Sat, 17 Nov 2007 04:06:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2007/11/17/36786.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/36786.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2007/11/17/36786.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/36786.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/36786.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/ngaut/archive/2007/11/17/36786.html'>阅读全文</a><img src ="http://www.cppblog.com/ngaut/aggbug/36786.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2007-11-17 12:06 <a href="http://www.cppblog.com/ngaut/archive/2007/11/17/36786.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>boost asio发送0字节的数据时,接收端提示"找不到指定文件"</title><link>http://www.cppblog.com/ngaut/archive/2007/10/23/34937.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Tue, 23 Oct 2007 11:16:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2007/10/23/34937.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/34937.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2007/10/23/34937.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/34937.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/34937.html</trackback:ping><description><![CDATA[<p><br>asio点滴:</p>
<p>采用tcp连接发送数据时,如果发送的数据的size是0,那么接收端会提示"找不到指定文件"</p>
<img src ="http://www.cppblog.com/ngaut/aggbug/34937.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2007-10-23 19:16 <a href="http://www.cppblog.com/ngaut/archive/2007/10/23/34937.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>release版本的程序提示需要MFC42D.dll的原因</title><link>http://www.cppblog.com/ngaut/archive/2007/04/30/23246.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Mon, 30 Apr 2007 07:43:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2007/04/30/23246.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/23246.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2007/04/30/23246.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/23246.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/23246.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;release版本的程序中使用的DLL是debug版本的^_^
<img src ="http://www.cppblog.com/ngaut/aggbug/23246.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2007-04-30 15:43 <a href="http://www.cppblog.com/ngaut/archive/2007/04/30/23246.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>boost::asio异步tcp传送文件的源代码</title><link>http://www.cppblog.com/ngaut/archive/2007/04/12/21715.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Thu, 12 Apr 2007 06:20:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2007/04/12/21715.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/21715.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2007/04/12/21715.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/21715.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/21715.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/ngaut/archive/2007/04/12/21715.html'>阅读全文</a><img src ="http://www.cppblog.com/ngaut/aggbug/21715.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2007-04-12 14:20 <a href="http://www.cppblog.com/ngaut/archive/2007/04/12/21715.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>UDP局域网广播的问题</title><link>http://www.cppblog.com/ngaut/archive/2007/04/11/21676.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Wed, 11 Apr 2007 15:04:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2007/04/11/21676.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/21676.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2007/04/11/21676.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/21676.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/21676.html</trackback:ping><description><![CDATA[<p>客户端和服务端使用相同的端口，通讯方式：服务端采用广播，客户端单播。<br></p>
<p>广播出去的包服务端自己也会收到一份，需要过滤(可以通过检测IP)，麻烦，貌似对效率有一点小小的影响，更好的方法是客户端和服务端使用不同的端口。<br>如服务端监听67端口，客户端监听68端口，服务端广播的包是发到67端口的，故监听68端口就不会收到自己发的广播包了^_^</p>
<img src ="http://www.cppblog.com/ngaut/aggbug/21676.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2007-04-11 23:04 <a href="http://www.cppblog.com/ngaut/archive/2007/04/11/21676.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>看了两天boost::asio网络库相关的资料，写了个小程序用异步tcp方式来传文件，果然高效，速度稳定在10M/s左右</title><link>http://www.cppblog.com/ngaut/archive/2007/04/10/21612.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Tue, 10 Apr 2007 12:09:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2007/04/10/21612.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/21612.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2007/04/10/21612.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/21612.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/21612.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/ngaut/archive/2007/04/10/21612.html'>阅读全文</a><img src ="http://www.cppblog.com/ngaut/aggbug/21612.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2007-04-10 20:09 <a href="http://www.cppblog.com/ngaut/archive/2007/04/10/21612.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vc++2005 boost 相关 </title><link>http://www.cppblog.com/ngaut/archive/2007/04/06/21365.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Thu, 05 Apr 2007 16:40:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2007/04/06/21365.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/21365.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2007/04/06/21365.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/21365.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/21365.html</trackback:ping><description><![CDATA[<p>输入命令行参数的地方：</p>
<p>项目：属性：配置属性：调试：命令参数<br><br></p>
<p>建议预处理器中加入宏BOOST_ALL_NO_LIB避免一些问题</p>
<p>&nbsp;</p>
<img src ="http://www.cppblog.com/ngaut/aggbug/21365.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2007-04-06 00:40 <a href="http://www.cppblog.com/ngaut/archive/2007/04/06/21365.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>解决unresolved external symbol "public: int __thiscall CWnd::KillTimer(unsigned int)" (?KillTimer@CWnd@@QAEHI@Z)问题</title><link>http://www.cppblog.com/ngaut/archive/2007/02/23/18933.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Fri, 23 Feb 2007 15:48:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2007/02/23/18933.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/18933.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2007/02/23/18933.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/18933.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/18933.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 解决KillTimer link失败的问题&nbsp;&nbsp;<a href='http://www.cppblog.com/ngaut/archive/2007/02/23/18933.html'>阅读全文</a><img src ="http://www.cppblog.com/ngaut/aggbug/18933.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2007-02-23 23:48 <a href="http://www.cppblog.com/ngaut/archive/2007/02/23/18933.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Google Talk library – libjingle 测试笔记</title><link>http://www.cppblog.com/ngaut/archive/2007/02/09/18568.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Fri, 09 Feb 2007 01:32:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2007/02/09/18568.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/18568.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2007/02/09/18568.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/18568.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/18568.html</trackback:ping><description><![CDATA[
		<h4 class="TextColor1" id="subjcns!ECCDDFB2EC6A263!128" style="MARGIN-BOTTOM: 0px">转自：<a href="http://readingmemos.spaces.live.com/blog/cns!ECCDDFB2EC6A263!128.entry">http://readingmemos.spaces.live.com/blog/cns!ECCDDFB2EC6A263!128.entry</a></h4>
		<h4 class="TextColor1" style="MARGIN-BOTTOM: 0px">Google Talk library – libjingle 测试笔记</h4>
		<div id="msgcns!ECCDDFB2EC6A263!128">
				<ol>
						<li>下载 
<p>http://prdownloads.sourceforge.net/libjingle/libjingle-0.3.0.zip?download </p></li>
						<li>下载expat XML Parser 
<p>http://sourceforge.net/project/showfiles.php?group_id=10127&amp;package_id=11277 </p></li>
						<li>Install expat 
</li>
						<li>Open the libjingle.sln 
</li>
						<li>Add lib path expat-VERSION\StaticLibs 
</li>
						<li>Add include path: expat-VERSION\Source\Lib 
</li>
						<li>Goto <a href="http://developer.globalipsound.com/"><font color="#006629">http://developer.globalipsound.com</font></a></li>
						<li>Registrer first 
</li>
						<li>Download 
</li>
						<li>unzip and put it into third_party\gips\Interface 
</li>
						<li>modify the expiration.h 
</li>
						<li>build 
</li>
						<li>if has error: has no netfw.h, download from SDK, or just from <a href="http://www.codeproject.com/w2k/WinXPSP2Firewall.asp"><font color="#006629">http://www.codeproject.com/w2k/WinXPSP2Firewall.asp</font></a></li>
						<li>
						</li>
				</ol>
		</div>
<img src ="http://www.cppblog.com/ngaut/aggbug/18568.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2007-02-09 09:32 <a href="http://www.cppblog.com/ngaut/archive/2007/02/09/18568.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]OnDraw()和OnPaint()兄弟</title><link>http://www.cppblog.com/ngaut/archive/2007/02/06/18476.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Tue, 06 Feb 2007 08:41:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2007/02/06/18476.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/18476.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2007/02/06/18476.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/18476.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/18476.html</trackback:ping><description><![CDATA[
		<table style="TABLE-LAYOUT: fixed; WORD-BREAK: break-all" cellspacing="0" cellpadding="0" width="90%" border="0">
				<tbody>
						<tr>
								<td class="oblog_t_4">
										<span class="style1">
												<font size="3">OnDraw()和OnPaint()兄弟</font>
										</span>
								</td>
						</tr>
						<tr>
								<td>
										<table cellspacing="0" cellpadding="0" width="100%" border="0">
												<tbody>
														<tr>
																<td>
																		<div align="right">
																				<span class="oblog_text">
																				</span> </div>
																</td>
														</tr>
												</tbody>
										</table>
										<span class="oblog_text">
												<br />
												<br />
												<br />经常有朋友问雷神这样的问题：<br />我在视图画的图象或者文字，当窗口改变后为什么不见了？<br />OnDraw()和OnPaint()两个都是解决上面的问题，有什么不同？<br /><br />雷神在这里一并解答一下吧。<br />OnDraw()和OnPaint()好象兄弟俩，因为它们的工作类似。<br /><br />至于不见了的问题简单，因为当你的窗口改变后，会产生无效区域，这个无效的区域需要重画。一般Windows回发送两个消息WM_PAINT（通知客户区有变化）和WM_NCPAINT（通知非客户区有变化）。非客户区的重画系统自己搞定了，而客户区的重画需要我们自己来完成。这就需要OnDraw()或OnPaint()来重画窗口。<br /><br />OnDraw()和OnPaint()有什么区别呢？<br />首先：<br />我们先要明确CView类派生自CWnd类。而OnPaint()是CWnd的类成员，同时负责响应WM_PAINT消息。OnDraw()是CVIEW的成员函数，并且没有响应消息的功能。这就是为什么你用VC成的程序代码时，在视图类只有OnDraw没有OnPaint的原因。<br /><br />其次：<br />我们在第《每天跟我学MFC》3的开始部分已经说到了。要想在屏幕上绘图或显示图形，首先需要建立设备环境DC。其实DC是一个数据结构，它包含输出设备（不单指你17寸的纯屏显示器，还包括打印机之类的输出设备）的绘图属性的描述。MFC提供了CPaintDC类和CWindwoDC类来实时的响应，而CPaintDC支持重画。<br /><br />当视图变得无效时（包括大小的改变，移动，被遮盖等等），Windows 将 WM_PAINT 消息发送给它。该视图的 OnPaint 处理函数通过创建 CPaintDC 类的DC对象来响应该消息并调用视图的 OnDraw 成员函数。通常我们不必编写重写的 OnPaint 处理成员函数。<br /><br />///CView默认的标准的重画函数<br />void CView::OnPaint()<br />{<br />    CPaintDC dc(this);<br />    OnPreparDC(&amp;dc)；<br />    OnDraw(&amp;dc); //调用了OnDraw<br />}<br /><br />既然OnPaint最后也要调用OnDraw,因此我们一般会在OnDraw函数中进行绘制。下面是一个典型的程序<br /><br />///视图中的绘图代码首先检索指向文档的指针，然后通过DC进行绘图调用。<br />void CMyView::OnDraw( CDC* pDC )<br />{<br />    CMyDoc* pDoc = GetDocument();<br />    CString s = pDoc-&gt;GetData();   // Returns a CString<br />    CRect rect;<br /><br />    GetClientRect( &amp;rect );<br />    pDC-&gt;SetTextAlign( TA_BASELINE | TA_CENTER );<br />    pDC-&gt;TextOut( rect.right / 2, rect.bottom / 2, <br />                  s, s.GetLength() );<br />}<br /><br />最后：<br />现在大家明白这哥俩之间的关系了吧。因此我们一般用OnPaint维护窗口的客户区（例如我们的窗口客户区加一个背景图片），用OnDraw维护视图的客户区（例如我们通过鼠标在视图中画图）。当然你也可以不按照上面规律来，只要达到目的并且没有问题，怎么干都成。<br /><br />补充：<br />我们还可以利用Invalidate(),ValidateRgn(),ValidateRect()函数强制的重画窗口，具体的请参考MSDN吧。<br /></span>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cppblog.com/ngaut/aggbug/18476.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2007-02-06 16:41 <a href="http://www.cppblog.com/ngaut/archive/2007/02/06/18476.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>miscellaneous的一个代码文件,使用了一些移植技巧和常用的技巧,记录之,备用</title><link>http://www.cppblog.com/ngaut/archive/2007/02/04/18322.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Sun, 04 Feb 2007 07:19:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2007/02/04/18322.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/18322.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2007/02/04/18322.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/18322.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/18322.html</trackback:ping><description><![CDATA[
		<p> </p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">/*</span>
				<span style="COLOR: #008000"> misc.h - miscellaneous interfaces </span>
				<span style="COLOR: #008000">*/</span>
				<span style="COLOR: #000000">
						<br />
						<br />
				</span>
				<span style="COLOR: #008000">/*</span>
				<span style="COLOR: #008000"> SimpleScalar(TM) Tool Suite<br /> * Copyright (C) 1994-2003 by Todd M. Austin, Ph.D. and SimpleScalar, LLC.<br /> * All Rights Reserved. <br /> * <br /> * THIS IS A LEGAL DOCUMENT, BY USING SIMPLESCALAR,<br /> * YOU ARE AGREEING TO THESE TERMS AND CONDITIONS.<br /> * <br /> * No portion of this work may be used by any commercial entity, or for any<br /> * commercial purpose, without the prior, written permission of SimpleScalar,<br /> * LLC (info@simplescalar.com). Nonprofit and noncommercial use is permitted<br /> * as described below.<br /> * <br /> * 1. SimpleScalar is provided AS IS, with no warranty of any kind, express<br /> * or implied. The user of the program accepts full responsibility for the<br /> * application of the program and the use of any results.<br /> * <br /> * 2. Nonprofit and noncommercial use is encouraged. SimpleScalar may be<br /> * downloaded, compiled, executed, copied, and modified solely for nonprofit,<br /> * educational, noncommercial research, and noncommercial scholarship<br /> * purposes provided that this notice in its entirety accompanies all copies.<br /> * Copies of the modified software can be delivered to persons who use it<br /> * solely for nonprofit, educational, noncommercial research, and<br /> * noncommercial scholarship purposes provided that this notice in its<br /> * entirety accompanies all copies.<br /> * <br /> * 3. ALL COMMERCIAL USE, AND ALL USE BY FOR PROFIT ENTITIES, IS EXPRESSLY<br /> * PROHIBITED WITHOUT A LICENSE FROM SIMPLESCALAR, LLC (info@simplescalar.com).<br /> * <br /> * 4. No nonprofit user may place any restrictions on the use of this software,<br /> * including as modified by the user, by any other authorized user.<br /> * <br /> * 5. Noncommercial and nonprofit users may distribute copies of SimpleScalar<br /> * in compiled or executable form as set forth in Section 2, provided that<br /> * either: (A) it is accompanied by the corresponding machine-readable source<br /> * code, or (B) it is accompanied by a written offer, with no time limit, to<br /> * give anyone a machine-readable copy of the corresponding source code in<br /> * return for reimbursement of the cost of distribution. This written offer<br /> * must permit verbatim duplication by anyone, or (C) it is distributed by<br /> * someone who received only the executable form, and is accompanied by a<br /> * copy of the written offer of source code.<br /> * <br /> * 6. SimpleScalar was developed by Todd M. Austin, Ph.D. The tool suite is<br /> * currently maintained by SimpleScalar LLC (info@simplescalar.com). US Mail:<br /> * 2395 Timbercrest Court, Ann Arbor, MI 48105.<br /> * <br /> * Copyright (C) 1994-2003 by Todd M. Austin, Ph.D. and SimpleScalar, LLC.<br /> </span>
				<span style="COLOR: #008000">*/</span>
				<span style="COLOR: #000000">
						<br />
						<br />
				</span>
				<span style="COLOR: #008000">/*</span>
				<span style="COLOR: #008000">*<br />工具函数文件<br /><br />这个文件定义了一些通用的工具函数<br /><br />@file misc.h<br />@author www.simplescalar.com(编写)<br />@author xieyubo@gmail.com(中文注释)<br /></span>
				<span style="COLOR: #008000">*/</span>
				<span style="COLOR: #000000">
						<br />
						<br />#ifndef MISC_H<br /></span>
				<span style="COLOR: #0000ff">#define</span>
				<span style="COLOR: #000000"> MISC_H</span>
				<span style="COLOR: #000000">
						<br />
						<br />#include </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">stdio.h</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />#include </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">stdlib.h</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />#include </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">stdarg.h</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />#include </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #0000ff">string</span>
				<span style="COLOR: #000000">.h</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />#include </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">sys</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">types.h</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<br />
				</span>
				<span style="COLOR: #008000">/*</span>
				<span style="COLOR: #008000"> boolean value defs </span>
				<span style="COLOR: #008000">*/</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #808080">///</span>
				<span style="COLOR: #008000"> 定义一些bool值</span>
				<span style="COLOR: #808080">
						<br />
				</span>
				<span style="COLOR: #000000">#ifndef TRUE<br /></span>
				<span style="COLOR: #0000ff">#define</span>
				<span style="COLOR: #000000"> TRUE 1</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #0000ff">#endif</span>
				<span style="COLOR: #000000">
						<br />#ifndef FALSE<br /></span>
				<span style="COLOR: #0000ff">#define</span>
				<span style="COLOR: #000000"> FALSE 0</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #0000ff">#endif</span>
				<span style="COLOR: #000000">
						<br />
						<br />
				</span>
				<span style="COLOR: #008000">/*</span>
				<span style="COLOR: #008000"> various useful macros </span>
				<span style="COLOR: #008000">*/</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #808080">///</span>
				<span style="COLOR: #008000"> 定义求最大数的宏</span>
				<span style="COLOR: #808080">
						<br />
				</span>
				<span style="COLOR: #000000">#ifndef MAX<br /></span>
				<span style="COLOR: #0000ff">#define</span>
				<span style="COLOR: #000000"> MAX(a, b)    (((a) &lt; (b)) ? (b) : (a))</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #0000ff">#endif</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #808080">///</span>
				<span style="COLOR: #008000"> 定义求最小数的宏</span>
				<span style="COLOR: #808080">
						<br />
				</span>
				<span 