﻿<?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++博客-ioriiod0</title><link>http://www.cppblog.com/ioriiod0/</link><description /><language>zh-cn</language><lastBuildDate>Mon, 13 Apr 2026 09:40:22 GMT</lastBuildDate><pubDate>Mon, 13 Apr 2026 09:40:22 GMT</pubDate><ttl>60</ttl><item><title>C++ 协程与网络编程</title><link>http://www.cppblog.com/ioriiod0/archive/2013/01/01/196890.html</link><dc:creator>江浸月</dc:creator><author>江浸月</author><pubDate>Tue, 01 Jan 2013 05:14:00 GMT</pubDate><guid>http://www.cppblog.com/ioriiod0/archive/2013/01/01/196890.html</guid><wfw:comment>http://www.cppblog.com/ioriiod0/comments/196890.html</wfw:comment><comments>http://www.cppblog.com/ioriiod0/archive/2013/01/01/196890.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/ioriiod0/comments/commentRss/196890.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ioriiod0/services/trackbacks/196890.html</trackback:ping><description><![CDATA[<h3>协程</h3><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">协程，即协作式程序，其思想是，一系列互相依赖的协程间依次使用CPU，每次只有一个协程工作，而其他协程处于休眠状态。协程可以在运行期间的某个点上暂停执行，并在恢复运行时从暂停的点上继续执行。 协程已经被证明是一种非常有用的程序组件，不仅被python、lua、ruby等脚本语言广泛采用，而且被新一代面向多核的编程语言如golang rust-lang等采用作为并发的基本单位。 协程可以被认为是一种用户空间线程，与传统的线程相比，有2个主要的优点：</p><ul style="padding: 0px; margin: 0px 0px 10px 20px; list-style-position: inside; font-family: Verdana, sans-serif, 宋体; line-height: normal; background-color: #ffffff;"><li style="padding: 0px; margin: 0px;">与线程不同，协程是自己主动让出CPU，并交付他期望的下一个协程运行，而不是在任何时候都有可能被系统调度打断。因此协程的使用更加清晰易懂，并且多数情况下不需要锁机制。</li><li style="padding: 0px; margin: 0px;">与线程相比，协程的切换由程序控制，发生在用户空间而非内核空间，因此切换的代价非常小。</li></ul><h3>网络编程模型</h3><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">首先来简单回顾一下一些常用的网络编程模型。网络编程模型可以大体的分为同步模型和异步模型两类。</p><ul style="padding: 0px; margin: 0px 0px 10px 20px; list-style-position: inside; font-family: Verdana, sans-serif, 宋体; line-height: normal; background-color: #ffffff;"><li style="padding: 0px; margin: 0px;">同步模型：</li></ul><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">同步模型使用阻塞IO模式,在阻塞IO模式下调用read等IO函数时会阻塞线程直到IO完成或失败。</p><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">同步模型的典型代表是thread per connection模型，每当阻塞在主线程上的accept调用返回时则创建一个新的线程去服务于新的socket的读/写。这种模型的优点是程序简洁，编写简单；缺点是可伸缩性收到线程数的限制，当连接越来越多时，线程也越来越多，频繁的线程切换会严重拖累性能。</p><ul style="padding: 0px; margin: 0px 0px 10px 20px; list-style-position: inside; font-family: Verdana, sans-serif, 宋体; line-height: normal; background-color: #ffffff;"><li style="padding: 0px; margin: 0px;">异步模型：</li></ul><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">异步模型一般使用非阻塞IO模式，并配合epoll/select/poll等多路复用机制。在非阻塞模式下调用read，如果没有数据可读则立即返回并通知用户没有可读（EAGAIN/EWOULDBLOCK），而非阻塞当前线程。异步模型可以使一个线程同时服务于多个IO对象。</p><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">异步模型的典型代表是reactor模型。在reactor模型中，我们将所有要处理的IO事件注册到一个中心的IO多路复用器中（一般为epoll/select/poll），同时主线程阻塞在多路复用器上。一旦有IO事件到来或者就绪，多路复用器返回并将对应的IO事件分发到对应的处理器（即回调函数）中，最后处理器调用read/write函数来进行IO操作。</p><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">异步模型的特点是性能和可伸缩性比同步模型要好很多，但是其结构复杂，不易于编写和维护。在异步模型中，IO之前的代码（IO任务的提交者）和IO之后的处理代码（回调函数）是割裂开来的。</p><h3>协程与网络编程</h3><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">协程为克服同步模型和异步模型的缺点，并结合他们的优点提供了可能： 现在假设我们有3个协程A,B,C分别要进行数次IO操作。这3个协程运行在同一个调度器或者说线程的上下文中，并依次使用CPU。调度器在其内部维护了一个多路复用器（epoll/select/poll）。</p><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">协程A首先运行，当它执行到一个IO操作，但该IO操作并没有立即就绪时，A将该IO事件注册到调度器中，并主动放弃CPU。这时调度器将B切换到CPU上开始执行，同样，当它碰到一个IO操作的时候将IO事件注册到调度器中，并主动放弃CPU。调度器将C切换到cpu上开始执行。当所有协程都被&#8220;阻塞&#8221;后，调度器检查注册的IO事件是否发生或就绪。假设此时协程B注册的IO时间已经就绪，调度器将恢复B的执行，B将从上次放弃CPU的地方接着向下运行。A和C同理。</p><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">这样，对于每一个协程来说，是同步的模型；但是对于整个应用程序来说，却是异步的模型。</p><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">好了，原理说完了，我们来看一个实际的例子，echo server。</p><h3>echo server</h3><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">在这个例子中，我们将使用orchid库来编写一个echo server。<a href="https://github.com/ioriiod0/orchid" rel="nofollow" style="padding: 0px; margin: 0px; color: #4466bb; outline: 0px;">orchid</a>库是一个构建于boost基础上的 协程/网络IO 库。</p><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">echo server首先必须要处理连接事件，我们创建一个协程来专门处理连接事件：</p><pre style="padding: 5px; margin-top: 10px; margin-bottom: 10px; line-height: 18px; font-size: 9pt; font-family: 'Courier New', Arial; border-width: 1px 1px 1px 5px; border-style: solid; border-color: #dddddd #dddddd #dddddd #6ce26c; background-color: #f6f6f6;"><code style="padding: 0px; margin: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">typedef boost::shared_ptr&lt;orchid::socket&gt; socket_ptr; <br />//处理ACCEPT事件的协程 <br />void handle_accept(orchid::coroutine_handle co) {<br />     try {         <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;orchid::acceptor acceptor(co -&gt; get_scheduler().get_io_service());//构建一个acceptor<br />         acceptor.bind_and_listen("5678",true);         <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(;;) {             <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;socket_ptr sock(new orchid::socket(co -&gt; get_scheduler().get_io_service()));<br />            acceptor.accept(*sock,co);             <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color: transparent; font-family: 'Courier New', Arial; font-size: 9pt;">//在调度器上创建一个协程来服务新的socket。</span><span style="background-color: transparent; font-family: 'Courier New', Arial; font-size: 9pt;">第一个参数是要创建的协程的main函数，</span><span style="background-color: transparent; font-family: 'Courier New', Arial; font-size: 9pt;">第二个参数是要创建的协程的栈的大小。</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;co -&gt; get_scheduler().spawn(boost::bind(handle_io,_1,sock),orchid::minimum_stack_size());<br />         }<br />     }&nbsp;catch(boost::system::system_error&amp; e) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cerr&lt;&lt;e.code()&lt;&lt;" "&lt;&lt;e.what()&lt;&lt;endl;<br />     } <br />} </code></pre><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">在orchid中，协程的main函数必须满足函数签名void(orchid::coroutine_handle)，如handle_accept所示，其中参数co是协程句柄，代表了当前函数所位于的协程。</p><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">在上面的代码中，我们创建了一个acceptor，并让它监听5678端口，然后在"阻塞"等待连接到来，当连接事件到来时，创建一个新的协程来服务新的socket。处理套接字IO的协程如下：</p><pre style="padding: 5px; margin-top: 10px; margin-bottom: 10px; line-height: 18px; font-size: 9pt; font-family: 'Courier New', Arial; border-width: 1px 1px 1px 5px; border-style: solid; border-color: #dddddd #dddddd #dddddd #6ce26c; background-color: #f6f6f6;"><code style="padding: 0px; margin: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">//处理SOCKET IO事件的协程 <br />void handle_io(orchid::coroutine_handle co,socket_ptr sock) {     <br />&nbsp;&nbsp;&nbsp;orchid::tcp_ostream out(*sock,co);     <br />&nbsp;&nbsp;&nbsp;orchid::tcp_istream in(*sock,co);     <br />&nbsp;&nbsp;&nbsp;for(std::string str;std::getline(in, str) &amp;&amp; out;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out&lt;&lt;str&lt;&lt;endl;     <br />&nbsp;&nbsp;&nbsp;}  <br />} </code></pre><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">IO处理协程首先在传入的套接字上创建了一个输入流和一个输出流，分别代表了TCP的输入和输出。然后不断地从输入流中读取一行，并输出到输出流当中。当socket上的TCP连接断开时，输入流和输出流的eof标志为会被置位，因此循环结束，协程退出。</p><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">orchid可以使用户以流的形式来操作套接字。输入流和输出流分别提供了std::istream和std::ostream的接口；输入流和输出流是带缓冲的，如果用户需要无缓冲的读写socket或者自建缓冲，可以直接调用orchid::socket的read和write函数。但是需要注意这两个函数会抛出boost::system_error异常来表示错误。</p><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">细心的读者可能已经发现，handle_io的函数签名并不满足void(orchid::coroutine_handle)，回到handle_accept中，可以发现，实际上我们使用了boost.bind对handle _ io函数进行了适配，使之符合函数签名的要求。</p><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">最后是main函数：</p><pre style="padding: 5px; margin-top: 10px; margin-bottom: 10px; line-height: 18px; font-size: 9pt; font-family: 'Courier New', Arial; border-width: 1px 1px 1px 5px; border-style: solid; border-color: #dddddd #dddddd #dddddd #6ce26c; background-color: #f6f6f6;"><code style="padding: 0px; margin: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">int main() {     <br />&nbsp;&nbsp;&nbsp;orchid::scheduler sche;     <br />&nbsp;&nbsp;&nbsp;sche.spawn(handle_accept,orchid::coroutine::minimum_stack_size());//创建协程     <br />&nbsp;&nbsp;&nbsp;sche.run(); <br />} </code></pre><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">在上面这个echo server的例子中，我们采用了一种 coroutine per connection 的编程模型，与传统的 thread per connection 模型一样的简洁清晰，但是整个程序实际上运行在同一线程当中。</p><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">由于协程的切换开销远远小于线程，因此我们可以轻易的同时启动上千协程来同时服务上千连接，这是 thread per connection的模型很难做到的；在性能方面，整个底层的IO系统实际上是使用boost.asio这种高性能的异步io库实现的。而且与IO所费的时间相比，协程切换的开销基本可以忽略。</p><p style="padding: 0px; margin: 0px 0px 15pt; line-height: 1.5; letter-spacing: 1px; font-family: Verdana, sans-serif, 宋体; background-color: #ffffff;">因此通过协程，我们可以在保持同步IO模型简洁性的同时，获得近似于异步IO模型的高性能。</p><img src ="http://www.cppblog.com/ioriiod0/aggbug/196890.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ioriiod0/" target="_blank">江浸月</a> 2013-01-01 13:14 <a href="http://www.cppblog.com/ioriiod0/archive/2013/01/01/196890.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为std::tuple添加格式化/序列化支持</title><link>http://www.cppblog.com/ioriiod0/archive/2011/11/28/161049.html</link><dc:creator>江浸月</dc:creator><author>江浸月</author><pubDate>Sun, 27 Nov 2011 21:17:00 GMT</pubDate><guid>http://www.cppblog.com/ioriiod0/archive/2011/11/28/161049.html</guid><wfw:comment>http://www.cppblog.com/ioriiod0/comments/161049.html</wfw:comment><comments>http://www.cppblog.com/ioriiod0/archive/2011/11/28/161049.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ioriiod0/comments/commentRss/161049.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ioriiod0/services/trackbacks/161049.html</trackback:ping><description><![CDATA[<div><h1><span style="line-height: normal; ">转载请注明出处。谢谢</span></h1></div>C++11中有很多激动人心的特性,但是相应的使得C++更加复杂。。。<br /><font class="Apple-style-span" face="Simsun" size="3"><span class="Apple-style-span" style="line-height: normal; ">新标准还修改了原有标准库，并增加了很多内容。<br /><br />在学习新标准的过程中动手写了个 为std::tuple增加格式化/序列化能力的一小段代码<br /><br /><div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;DECLARE_TUPLE_SERIALIZATION_FUNCTION(FUNC_NAME,BEG,SEP,END)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">namespace</span><span style="color: #000000; ">&nbsp;sjdfsjfyttsaihfah6755jsdf554433356sdf{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />template&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">typename&nbsp;Tuple,std::size_t&nbsp;N</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br /></span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;tuple_printer&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;print(std::ostream</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;os,</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;Tuple</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;t)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">std::</span><span style="color: #0000FF; ">get</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">std::tuple_size</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Tuple</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">::value&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;N&nbsp;</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">(t)</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">SEP;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tuple_printer</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Tuple,N</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">::print(os,t);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />};&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />template&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">typename&nbsp;Tuple</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br /></span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;tuple_printer</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Tuple,</span><span style="color: #000000; ">1</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;print(std::ostream</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;os,</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;Tuple</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;t)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">std::</span><span style="color: #0000FF; ">get</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">std::tuple_size</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Tuple</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">::value</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">(t);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />};&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />template&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">typename&nbsp;Tuple</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;FUNC_NAME(std::ostream</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;os,</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;Tuple</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;t)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;os</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">BEG;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;sjdfsjfyttsaihfah6755jsdf554433356sdf::tuple_printer</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Tuple,std::tuple_size</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Tuple</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">::value</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">::print(os,t);&nbsp;&nbsp;&nbsp;&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;os</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">END;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br />} &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<br /></span></div></span></font><font class="Apple-style-span" face="Simsun" size="3"><span class="Apple-style-span" style="line-height: normal; ">实现成宏是为了使用起来更方便，可以随意指定 函数名 前缀 分隔符 和 后缀。<br />使用方法如下：<br /><br /><div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">DECLARE_TUPLE_SERIALIZATION_FUNCTION(serialize_tuple,</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">)<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;main()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">10</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;auto&nbsp;a&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;std::make_tuple(</span><span style="color: #000000; ">3</span><span style="color: #000000; ">,</span><span style="color: #000000; ">"</span><span style="color: #000000; ">lala</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,i,</span><span style="color: #000000; ">'</span><span style="color: #000000; ">c</span><span style="color: #000000; ">'</span><span style="color: #000000; ">);</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;serialize_tuple(std::cout,a);&nbsp;<br />}</span></div><br />输出为：<br />&lt;3 , "lala" , 10 , c&gt;<br /><br />测试环境为GCC 4.5，注意编译时候请打开C++0X支持。<br /><br /><br /></span></font><img src ="http://www.cppblog.com/ioriiod0/aggbug/161049.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ioriiod0/" target="_blank">江浸月</a> 2011-11-28 05:17 <a href="http://www.cppblog.com/ioriiod0/archive/2011/11/28/161049.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>做MTK笔试的总结（二）－－C＋＋ 返回值优化（RVO）</title><link>http://www.cppblog.com/ioriiod0/archive/2011/08/13/153300.html</link><dc:creator>江浸月</dc:creator><author>江浸月</author><pubDate>Sat, 13 Aug 2011 13:38:00 GMT</pubDate><guid>http://www.cppblog.com/ioriiod0/archive/2011/08/13/153300.html</guid><wfw:comment>http://www.cppblog.com/ioriiod0/comments/153300.html</wfw:comment><comments>http://www.cppblog.com/ioriiod0/archive/2011/08/13/153300.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/ioriiod0/comments/commentRss/153300.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ioriiod0/services/trackbacks/153300.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff; ">题目二：<br />&nbsp; &nbsp;题目我做了下改变，使用了上篇文章中提到的那个类X，代码如下：<br /><br /><div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;X<br /></span><span style="color: #008080; ">&nbsp;2</span>&nbsp;<span style="color: #000000; ">{<br /></span><span style="color: #008080; ">&nbsp;3</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">:<br /></span><span style="color: #008080; ">&nbsp;4</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;X(){cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">default&nbsp;construct</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;}<br /></span><span style="color: #008080; ">&nbsp;5</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;X(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;a):i(a){&nbsp;cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">construct&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">i</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;}<br /></span><span style="color: #008080; ">&nbsp;6</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">~</span><span style="color: #000000; ">X(){&nbsp;cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">desconstruct&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">i</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;}<br /></span><span style="color: #008080; ">&nbsp;7</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;X(</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;X</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;x):i(x.i)<br /></span><span style="color: #008080; ">&nbsp;8</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080; ">&nbsp;9</span>&nbsp;<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; ">"</span><span style="color: #000000; ">copy&nbsp;construct&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">i</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;<br /></span><span style="color: #008080; ">10</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">11</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;X</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">operator</span><span style="color: #000000; ">++</span><span style="color: #000000; ">()<br /></span><span style="color: #008080; ">12</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080; ">13</span>&nbsp;<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; ">"</span><span style="color: #000000; ">operator&nbsp;++(pre)&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">i</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;<br /></span><span style="color: #008080; ">14</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i;<br /></span><span style="color: #008080; ">15</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">16</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">17</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;X&nbsp;</span><span style="color: #0000FF; ">operator</span><span style="color: #000000; ">++</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">)<br /></span><span style="color: #008080; ">18</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080; ">19</span>&nbsp;<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; ">"</span><span style="color: #000000; ">operator&nbsp;++(post)&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">i</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;<br /></span><span style="color: #008080; ">20</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;X&nbsp;x(</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">21</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i;<br /></span><span style="color: #008080; ">22</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;x;<br /></span><span style="color: #008080; ">23</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">24</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;X</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">operator</span><span style="color: #000000; ">=</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;m)<br /></span><span style="color: #008080; ">25</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080; ">26</span>&nbsp;<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; ">"</span><span style="color: #000000; ">operator&nbsp;=(int)</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;<br /></span><span style="color: #008080; ">27</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;m;<br /></span><span style="color: #008080; ">28</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">29</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">30</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;X</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">operator</span><span style="color: #000000; ">=</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;X</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;x)<br /></span><span style="color: #008080; ">31</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080; ">32</span>&nbsp;<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; ">"</span><span style="color: #000000; ">operator&nbsp;=(X)</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;<br /></span><span style="color: #008080; ">33</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">x.i;<br /></span><span style="color: #008080; ">34</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">35</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">36</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080; ">////////////////////////</span><span style="color: #008000; ">/</span><span style="color: #808080; "><br /></span><span style="color: #008080; ">37</span>&nbsp;<span style="color: #808080; "></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;friend&nbsp;ostream</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">operator</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">(ostream</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;os,</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;X</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;x)<br /></span><span style="color: #008080; ">38</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080; ">39</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">x.i;<br /></span><span style="color: #008080; ">40</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;os;<br /></span><span style="color: #008080; ">41</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">42</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;friend&nbsp;X&nbsp;</span><span style="color: #0000FF; ">operator</span><span style="color: #000000; ">+</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;X</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;a,</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;X</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;b)<br /></span><span style="color: #008080; ">43</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080; ">44</span>&nbsp;<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; ">"</span><span style="color: #000000; ">operator&nbsp;+</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;<br /></span><span style="color: #008080; ">45</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;X(a.i</span><span style="color: #000000; ">+</span><span style="color: #000000; ">b.i);<br /></span><span style="color: #008080; ">46</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">47</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080; ">////////////////////////</span><span style="color: #008000; ">//</span><span style="color: #808080; "><br /></span><span style="color: #008080; ">48</span>&nbsp;<span style="color: #808080; "></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">:<br /></span><span style="color: #008080; ">49</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i;<br /></span><span style="color: #008080; ">50</span>&nbsp;<span style="color: #000000; ">};</span></div><br /></span>请问以下代码的输出是什么？<br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">1</span>&nbsp;<span style="color: #000000; ">X&nbsp;a(</span><span style="color: #000000; ">10</span><span style="color: #000000; ">),b(</span><span style="color: #000000; ">20</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">2</span>&nbsp;<span style="color: #000000; ">X&nbsp;c</span><span style="color: #000000; ">=</span><span style="color: #000000; ">a</span><span style="color: #000000; ">+</span><span style="color: #000000; ">b;</span></div><br />我们来看一下使用GCC4.5（默认编译选项）以及MSVC9.0(BOTH DEBUG AND RELEASE)编译后的实际运行结果：<br /><div><div>construct 10</div><div>construct 20</div><div>operator +</div><div>construct 30</div><div>desconstruct 30</div><div>desconstruct 20</div><div>desconstruct 10<br /><br />简单分析下这个输出：<br /><br /><div><div>construct 10&nbsp;</div><div>construct 20 //对应 X a(10),b(20);</div><div>operator + &nbsp;//调用&#8220;+&#8221;操作符</div><div>construct 30 //调用X(int){...}，44行处</div><div>desconstruct 30 //变量c 的析构</div><div>desconstruct 20 //变量b 的析构</div><div>desconstruct 10 //变量a 的析构</div></div>&nbsp;从结果可以看出，整个执行过程中没有输出&#8220;operator=&#8221;，说明压根没有调用&#8220;＝&#8221;操作符，而且整个过程比我想象的要简洁高效，没有临时对象，没有拷贝构造。<br />结果为什么会是这样呢？这主要归功于编译器的返回值优化的能力。<br />有关返回值优化的知识，限于篇幅我就不仔细介绍了，但是需要特别指出的是MSVC9.0只在RELEASE模式下默认开启NRVO，即对具名对象的返回值优化，以及返回值优化里面的一个重要的细节，体现在本例里就是：为什么中整个输出中没有出现"opeartor=",即为什么没调用"="操作符。<br /><br />现在我们将代码稍微改变一下，改成下面的样子:<br /><br /><div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">X&nbsp;a(</span><span style="color: #000000; ">10</span><span style="color: #000000; ">),b(</span><span style="color: #000000; ">20</span><span style="color: #000000; ">),c;<br />c</span><span style="color: #000000; ">=</span><span style="color: #000000; ">a</span><span style="color: #000000; ">+</span><span style="color: #000000; ">b; &nbsp;／／这里我们将c的构造和赋值分开了</span></div><br />执行的结果如下：<br /><br /><div><div>construct 10 ／／构造a</div><div>construct 20 ／／构造b</div><div>default construct ／／构造 c</div><div>operator + &nbsp;／／调用&#8220;+&#8221;操作符</div><div>construct 30 ／／调用X(int){...}，44行处</div><div>operator =(X) ／／调用&#8220;＝&#8221;操作符</div><div>desconstruct 30 ／／代码45行所建立的临时对象的析构</div><div>desconstruct 30 ／／变量c的析构</div><div>desconstruct 20 ／／变量b的析构</div><div>desconstruct 10 ／／变量c的析构<br /><br />对比前后的输出结果，可以发现多出以下三行</div></div><div><div>default construct&nbsp;</div></div><div>operator =(X)&nbsp;</div><div>desconstruct 30&nbsp;<br />出现这种差异的原因在于：<div style="display: inline-block; "></div><span class="Apple-style-span" style="color: #333333; font-family: Arial; background-color: #ffffff; ">定义c的时候会调用默认的构造函数进行初始化，因此第一条语句执行完之后，c已经是一个存在的对象，所以第二条语句并没有权利去直接修改c的内容，必须要通过调用赋值操作符&#8221;=&#8220;，因此必须要产生一个临时对象。而在第一个例子中，因为执行到第二条语句之前c并没有被创建,所以编译器可以将 表达式a+b的返回值直接构建在c的内存中，从而优化掉临时对象和对&#8220;＝&#8221;的调用。<br /></span></div></div></div><div></div><img src ="http://www.cppblog.com/ioriiod0/aggbug/153300.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ioriiod0/" target="_blank">江浸月</a> 2011-08-13 21:38 <a href="http://www.cppblog.com/ioriiod0/archive/2011/08/13/153300.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>做MTK笔试的总结（一）</title><link>http://www.cppblog.com/ioriiod0/archive/2011/08/13/153284.html</link><dc:creator>江浸月</dc:creator><author>江浸月</author><pubDate>Sat, 13 Aug 2011 09:30:00 GMT</pubDate><guid>http://www.cppblog.com/ioriiod0/archive/2011/08/13/153284.html</guid><wfw:comment>http://www.cppblog.com/ioriiod0/comments/153284.html</wfw:comment><comments>http://www.cppblog.com/ioriiod0/archive/2011/08/13/153284.html#Feedback</comments><slash:comments>19</slash:comments><wfw:commentRss>http://www.cppblog.com/ioriiod0/comments/commentRss/153284.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ioriiod0/services/trackbacks/153284.html</trackback:ping><description><![CDATA[今年要开始找工作了，本着积累经验的目的，跑去做了下MTK的笔试题，笔试的内容主要是C＋＋。<br />因为开发中一直使用C＋＋，而且对C＋＋里的高级特性：面向对象，模板等都比较熟悉，还没事喜欢研究下STL，BOOST，所以对自己的C＋＋水平比较自信，因此事先也没做任何准备，就直接去笔试了。本来笔试完了后觉得题目蛮简单的，但是本着认真学习的态度回来后把题目都上机试验了下，结果一下就悲剧了，错的体无完服啊。。。<br />总结了一下：<br />&nbsp;&nbsp;&nbsp;1。认真对待，不要小看了笔试题目：做题的时候心想这些笔试题目都很简单啊，很多题目都是扫了一眼就立即写出了答案，结果回来后才发现这些题目都设置了陷阱，让你掉进去就出不来了。<br />&nbsp; &nbsp;2。C＋＋基础不够扎实。枉我还一天到晚的研究C＋＋的高级特性，结果很多基础的知识却都是一知半解。<br />特将此次笔试的一些心得和体会记录于此，好提醒自己。下面主要分析几个我做错的题目。题目并非与原题完全一致。<br />题目一：<br /><div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;a</span><span style="color: #000000; ">=</span><span style="color: #000000; ">10</span><span style="color: #000000; ">,b</span><span style="color: #000000; ">=</span><span style="color: #000000; ">6</span><span style="color: #000000; ">;<br />cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">a</span><span style="color: #000000; ">+</span><span style="color: #000000; ">b</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">a</span><span style="color: #000000; ">++&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">b</span><span style="color: #000000; ">++</span><span style="color: #000000; ">;&nbsp;</span></div><br />请说出上述语句的执行结果。<br />很多人看过这段代码后估计都会直接就写上了 16 10 6 这样的结果吧，但上机实验的输出结果是： 18 10 6<br />为什么会出现这样的结果，下面是我的分析过程，如果有不对的地方请大家指正。<br />为了跟踪代码的执行步骤，我设计了一个类X，这个类是对int的模拟，行为方面与int基本一致，除了会打印出一些帮助我们理解的信息，代码如下：<br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;X<br />{<br /></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">:<br />&nbsp;&nbsp;&nbsp;&nbsp;X(){cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">default&nbsp;construct</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;}<br />&nbsp;&nbsp;&nbsp;&nbsp;X(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;a):i(a){&nbsp;cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">construct&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">i</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">~</span><span style="color: #000000; ">X(){&nbsp;cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">desconstruct&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">i</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;}<br />&nbsp;&nbsp;&nbsp;&nbsp;X(</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;X</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;x):i(x.i)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">copy&nbsp;construct&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">i</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;X</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">operator</span><span style="color: #000000; ">++</span><span style="color: #000000; ">()<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">operator&nbsp;++(pre)&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">i</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;X&nbsp;</span><span style="color: #0000FF; ">operator</span><span style="color: #000000; ">++</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">operator&nbsp;++(post)&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">i</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;X&nbsp;x(</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;x;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;X</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">operator</span><span style="color: #000000; ">=</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;m)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">operator&nbsp;=(int)</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;m;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;X</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">operator</span><span style="color: #000000; ">=</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;X</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;x)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">operator&nbsp;=(X)</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">x.i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080; ">////////////////////////</span><span style="color: #008000; ">/</span><span style="color: #808080; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;friend&nbsp;ostream</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">operator</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">(ostream</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;os,</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;X</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;x)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">x.i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;os;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;friend&nbsp;X&nbsp;</span><span style="color: #0000FF; ">operator</span><span style="color: #000000; ">+</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;X</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;a,</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;X</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;b)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">operator&nbsp;+</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">endl;<br /></span><span style="color: #0000ff; ">&nbsp; &nbsp; &nbsp; &nbsp; return</span><span style="color: #000000; ">&nbsp;X(a.i+b.i);</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080; ">////////////////////////</span><span style="color: #008000; ">//</span><span style="color: #808080; "><br /></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">:<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;i;<br />};</span></div><br />然后执行以下代码：<br /><br /><div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">&nbsp; &nbsp; X&nbsp;a(</span><span style="color: #000000; ">10</span><span style="color: #000000; ">),b(</span><span style="color: #000000; ">6</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">sum:</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">a</span><span style="color: #000000; ">+</span><span style="color: #000000; ">b</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;a:</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">a</span><span style="color: #000000; ">++&lt;&lt;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;b:</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">b</span><span style="color: #000000; ">++&lt;&lt;</span><span style="color: #000000; ">endl;<br /></span></div><br />使用GCC4。5编译后，代码的执行结果如下：<br /><br /><div><div><div><div>construct 10</div><div>construct 6</div><div>operator ++(post) 6</div><div>copy construct 6</div><div>operator ++(post) 10</div><div>copy construct 10</div><div>operator +</div><div>construct 18</div><div>sum:18 a:10 b:6</div><div>desconstruct 18</div><div>desconstruct 10</div><div>desconstruct 6</div><div>desconstruct 7</div><div>desconstruct 11</div></div><div></div></div></div><div>我们来简单分析下这个执行过程：</div><br /><div><div>construct 10</div><div>construct 6 &nbsp;／／这两行输出对应于 X a(10),b(6);&nbsp;<br /><br /><div><div>operator ++(post) 6</div><div>copy construct 6 ／／表明首先执行了&nbsp;&nbsp;cout&lt;&lt;"sum:" &lt;&lt;a+b&lt;&lt;" a:"&lt;&lt;a++&lt;&lt;" b:"&lt;&lt;b++&lt;&lt;endl;这句中的 b++这个表达式，<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b++这个表达式返回了一个值为6的临时对象，而b本身则变成了7。<br /><div style="display: inline-block; "><div><div><div></div><div>operator ++(post) 10 <br />copy construct 10 &nbsp;／／这句的分析同上<br /><br /><div><div>operator +</div><div>construct 18 //对应于表达式 a+b ,可以看到，此时的a和b已经变成了11和7。表达式返回了一个值为18的临时对象。<br /><br /><div>sum:18 a:10 b:6 ／／输出的结果，从结果可以看出，实际上打印出的值分别为 a+b,a++和b＋＋三个表达式所返回的临时变量。</div></div></div></div></div></div></div></div></div><span class="Apple-style-span" style="background-color: #eeeeee; "><span style="color: #000000; "><br /></span></span></div></div><div>desconstruct 18 ／／a＋b 表达式返回的临时变量的析构</div><div>desconstruct 10&nbsp;／／a＋＋ 表达式返回的临时变量的析构</div><div>desconstruct 6&nbsp;／／b＋＋表达式返回的临时变量的析构</div><div>desconstruct 7&nbsp;／／变量a 的析构</div><div>desconstruct 11 &nbsp;／／变量b的析构<br /><br />真相大白了。为什么编译器会这样来编译这个表达式呢？<br />下面2楼的夜风同学给出了正确答案。。为了不误导后面的同学，特此编辑掉。。<br /><br />上述实验的环境均为GCC4。5 &nbsp;据同学说VS2010执行的结果在DEBUG下和RELEASE下居然分别为：16 10 6 和18 10 6，不过我没有去验证过，有兴趣的同学可以去验证并分析一下。<br />做这样一道题还是让我收获很多，巩固了C＋＋的基础。<br />今天就写道这里，后面有时间会陆续放出对其他&#8220;陷阱&#8221;题目的分析。<br />（未完待续）</div><font class="Apple-style-span" color="#008080" size="2"><br /></font><img src ="http://www.cppblog.com/ioriiod0/aggbug/153284.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ioriiod0/" target="_blank">江浸月</a> 2011-08-13 17:30 <a href="http://www.cppblog.com/ioriiod0/archive/2011/08/13/153284.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对BOOST 中同步互斥的一些理解</title><link>http://www.cppblog.com/ioriiod0/archive/2011/05/26/147135.html</link><dc:creator>江浸月</dc:creator><author>江浸月</author><pubDate>Wed, 25 May 2011 17:10:00 GMT</pubDate><guid>http://www.cppblog.com/ioriiod0/archive/2011/05/26/147135.html</guid><wfw:comment>http://www.cppblog.com/ioriiod0/comments/147135.html</wfw:comment><comments>http://www.cppblog.com/ioriiod0/archive/2011/05/26/147135.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ioriiod0/comments/commentRss/147135.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ioriiod0/services/trackbacks/147135.html</trackback:ping><description><![CDATA[首先，BOOST中有4种有关互斥量得概念。<br />1.LOCKABLE :仅支持排它型所有权<br />2.TIMEDLOCKABLE：支持带超时的排它型所有权<br />3.SHAREDLOCKABLE： 支持带超时的排他型所有权和共享型所有权（读写锁）<br />4.UPGRADELOCKABLE：&nbsp;<div style="display: inline-block; "></div>支持带超时的排他型所有权和共享型所有权，以及共享型所有权升级为排他型所有权（升级过程阻塞）(也支持降级)<br /><br />可以看到2强化自1,3强化自2.4强化自3，支持某一概念则一定支持其强化自的概念。<br /><br />boost::mutex 实现了LOCKABLE概念 （boost::recursive_mutex 是其递归锁的版本）<br />boost::timed_mutex 实现了TIMEDLOCKABLE概念&nbsp;<div style="display: inline-block; "></div>（boost::recursive_timed_mutex 是其递归锁的版本）<br />boost::shared_mutex实现了SHAREDLOCKABLE概念<br />boost::shared_mutex同样实现了UPGRADELOCKABLE概念<br /><br />出于提供RAII操作风格和安全等其他一些原因BOOST不希望用户直接调用各种MUTEX类型中的相关接口，而是通过它提供的一些LOCK_TYPE来帮助我们调用。<br /><br />主要的LOCK_TYPE包括：<br /><br />boost::unique_lock&lt;LOCKABLE&gt; 针对支持LOCKABLE概念的类型（上述4中MUTEX类型都支持LOCKABLE概念）。以RAII的方式调用该类的lock()&nbsp;<div style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; display: inline-block; "></div>（调用成功后排它的独占该互斥量）和 unlock() 方法。<br /><br />boost::shared_lock&lt;SHAREDLOCKABLE&gt;针对支持SHAREDLOCKABLE概念的类型，boost::shared_mutex实现了该概念，注意，支持SHAREDLOCKABLE概念的类既支持排他的独占（写锁，通过调用lock unlock系列函数），也支持共享的方式占用（读锁，通过调用lock_shared系列），<div style="display: inline-block; "></div>shared_lock默认调用<div style="display: inline-block; "></div>lock_shared系列。<br /><br />最主要最常用的就是上面这两个LOCK类型，分别代表独占方式和共享方式，其他的就不一一分析了。<br /><br />下面是个从<a href="http://hi.baidu.com/jrckkyy/blog/item/d7ccb508dfba2e3ce8248817.html">http://hi.baidu.com/jrckkyy/blog/item/d7ccb508dfba2e3ce8248817.html</a>此处找到的例子<br /><br /><div><span class="Apple-style-span" style="color: #333333; font-family: Arial; font-size: 13px; line-height: 20px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; ">typedef&nbsp;<span class="hilite1" style="line-height: normal; ">boost</span>::shared_mutex rwmutex;&nbsp;<br style="line-height: normal; " />typedef&nbsp;<span class="hilite1" style="line-height: normal; ">boost</span>::shared_lock&lt;rwmutex&gt; readLock;&nbsp;<br style="line-height: normal; " />typedef&nbsp;<span class="hilite1" style="line-height: normal; ">boost</span>::uniq_lock&lt;rwmutex&gt; writeLock;&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />rwmutex&nbsp; _rwmutex;&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />void readOnly()&nbsp;<br style="line-height: normal; " />{&nbsp;<br style="line-height: normal; " />...&nbsp;<br style="line-height: normal; " />{ // 临界区&nbsp;<br style="line-height: normal; " />readLock rdlock<div style="display: inline-block; "></div></span><span class="Apple-style-span" style="color: #333333; font-family: Arial; font-size: 13px; line-height: 20px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; ">(_rwmutex)</span><span class="Apple-style-span" style="color: #333333; font-family: Arial; font-size: 13px; line-height: 20px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; ">;&nbsp;<br style="line-height: normal; " />...&nbsp;<br style="line-height: normal; " />do something&nbsp;<br style="line-height: normal; " />...&nbsp;<br style="line-height: normal; " />}&nbsp;<br style="line-height: normal; " />...&nbsp;<br style="line-height: normal; " />}&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />void writeOnly()&nbsp;<br style="line-height: normal; " />{&nbsp;<br style="line-height: normal; " />...&nbsp;<br style="line-height: normal; " />{ // 临界区&nbsp;<br style="line-height: normal; " />writeLock wlock(<div style="display: inline-block; "></div></span><span class="Apple-style-span" style="color: #333333; font-family: Arial; font-size: 13px; line-height: 20px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; ">_rwmutex</span><span class="Apple-style-span" style="color: #333333; font-family: Arial; font-size: 13px; line-height: 20px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; ">);&nbsp;<br style="line-height: normal; " />...&nbsp;<br style="line-height: normal; " />do something&nbsp;<br style="line-height: normal; " />...&nbsp;<br style="line-height: normal; " />}&nbsp;<br style="line-height: normal; " />...&nbsp;<br style="line-height: normal; " />}&nbsp;<br style="line-height: normal; " /></span></div><br /><br /><br /><br /><br /><br /><img src ="http://www.cppblog.com/ioriiod0/aggbug/147135.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ioriiod0/" target="_blank">江浸月</a> 2011-05-26 01:10 <a href="http://www.cppblog.com/ioriiod0/archive/2011/05/26/147135.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>