﻿<?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++博客-蜗牛的家-随笔分类-C\C++</title><link>http://www.cppblog.com/bangle/category/8010.html</link><description>男儿当自强</description><language>zh-cn</language><lastBuildDate>Thu, 24 Mar 2011 22:13:25 GMT</lastBuildDate><pubDate>Thu, 24 Mar 2011 22:13:25 GMT</pubDate><ttl>60</ttl><item><title>lamda的简单实现</title><link>http://www.cppblog.com/bangle/archive/2011/03/22/142527.html</link><dc:creator>黑色天使</dc:creator><author>黑色天使</author><pubDate>Tue, 22 Mar 2011 15:47:00 GMT</pubDate><guid>http://www.cppblog.com/bangle/archive/2011/03/22/142527.html</guid><wfw:comment>http://www.cppblog.com/bangle/comments/142527.html</wfw:comment><comments>http://www.cppblog.com/bangle/archive/2011/03/22/142527.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/bangle/comments/commentRss/142527.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/bangle/services/trackbacks/142527.html</trackback:ping><description><![CDATA[所谓Lambda，简单的说是快速的小函数生成.<br>在STL的算法中很多地方需要提供一个函数对象或仿函数如for_each<br>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><span style="color: #000000;">for_each(v.begin(),&nbsp;v.end(),&nbsp;op());&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">原格式如此<br></span></div>
如果需要不用的算法就需要些不同的函数对象，但是引用了万能的lambda后效果就不同了,效果如下<br>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><span style="color: #000000;">for_each(v.begin(),&nbsp;v.end(),&nbsp;_1</span><span style="color: #000000;">=</span><span style="color: #000000;">2</span><span style="color: #000000;">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">_1=2是一个仿函数,通过重载=实现<br></span></div>
需要的操作一目了然，简单分析下for_each第三个参数需要的是一个函数或仿函数，所以_1=2必然产生的是一个仿函数,大致可以推出是重载了=实现的产生仿函数，那么真正的操作还需要一个封装，即需要两个类实现，第一个类大致如下<br>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;place_holder<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">重载需要的算法操作</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;R</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;op</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">R</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">operator</span><span style="color: #000000;">=</span><span style="color: #000000;">(R&nbsp;i)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;op</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">R</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">(i);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>};</span></div>
模板使得这个结构可以传入任何类型的参数，通过重载=操作内部返回了一个仿函数，具体的操作由一下的仿函数实现<br>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><span style="color: #008000;">//</span><span style="color: #008000;">仿函数，即重载了()操作的类</span><span style="color: #008000;"><br></span><span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;op<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;op(T&nbsp;i):&nbsp;_i(i)&nbsp;{}<br>&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;</span><span style="color: #0000ff;">operator</span><span style="color: #000000;">()(T&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">i)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;_i;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;_i;<br>};</span></div>
这个仿函数将传入的引用参数进行了赋值操作，实现了最终的操作.<br>以上的代码实现=操作如果需要其他操作则重载相应的操作例如+=<br>依次类推占位类实现+=并通过仿函数可以实现+=的操作以下是完成的代码<br>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;lambda.cpp&nbsp;:&nbsp;定义控制台应用程序的入口点。<br></span><span style="color: #008000;">//<br></span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">stdafx.h</span><span style="color: #000000;">"</span><span style="color: #000000;"><br>#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>#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><br></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><br></span><span style="color: #008000;">//</span><span style="color: #008000;">仿函数，即重载了()操作的类</span><span style="color: #008000;"><br></span><span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;op<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;op(T&nbsp;i):&nbsp;_i(i)&nbsp;{}<br>&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;</span><span style="color: #0000ff;">operator</span><span style="color: #000000;">()(T&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">i)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;_i;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;_i;<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;op1<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;op1(T&nbsp;i):_i(i){}<br>&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;</span><span style="color: #0000ff;">operator</span><span style="color: #000000;">()(T&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">i)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;_i;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;_i;<br>};<br><br></span><span style="color: #008000;">//</span><span style="color: #008000;">占位符</span><span style="color: #008000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;place_holder<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">重载需要的算法操作</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;R</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;op</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">R</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">operator</span><span style="color: #000000;">=</span><span style="color: #000000;">(R&nbsp;i)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;op</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">R</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">(i);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;R</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;op1</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">R</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">operator</span><span style="color: #000000;">+=</span><span style="color: #000000;">(R&nbsp;i)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;op1</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">R</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">(i);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>};<br><br>place_holder&nbsp;_1;<br><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;_tmain(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;argc,&nbsp;_TCHAR</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;argv[])<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;vector</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;v;<br>&nbsp;&nbsp;&nbsp;&nbsp;v.push_back(</span><span style="color: #000000;">1</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;v.push_back(</span><span style="color: #000000;">2</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;v.push_back(</span><span style="color: #000000;">3</span><span style="color: #000000;">);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">for_each(v.begin(),&nbsp;v.end(),&nbsp;op());&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">原格式如此</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;for_each(v.begin(),&nbsp;v.end(),&nbsp;_1</span><span style="color: #000000;">=</span><span style="color: #000000;">2</span><span style="color: #000000;">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">_1=2是一个仿函数,通过重载=实现</span><span style="color: #008000;"><br></span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>}</span></div>
<br><br>    <img src ="http://www.cppblog.com/bangle/aggbug/142527.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/bangle/" target="_blank">黑色天使</a> 2011-03-22 23:47 <a href="http://www.cppblog.com/bangle/archive/2011/03/22/142527.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>YUV格式详细解释与FFMPEG的关系</title><link>http://www.cppblog.com/bangle/archive/2009/06/08/87070.html</link><dc:creator>黑色天使</dc:creator><author>黑色天使</author><pubDate>Mon, 08 Jun 2009 07:23:00 GMT</pubDate><guid>http://www.cppblog.com/bangle/archive/2009/06/08/87070.html</guid><wfw:comment>http://www.cppblog.com/bangle/comments/87070.html</wfw:comment><comments>http://www.cppblog.com/bangle/archive/2009/06/08/87070.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/bangle/comments/commentRss/87070.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/bangle/services/trackbacks/87070.html</trackback:ping><description><![CDATA[<div id=art width="100%">
<p align=left><strong><span>YUV</span></strong><strong><span>主要的采样格式</span></strong><strong><span> </span></strong></p>
<p align=left><span>主要的采样格式有</span><span>YCbCr 4:2:0</span><span>、</span><span>YCbCr 4:2:2</span><span>、</span><span>YCbCr 4:1:1</span><span>和</span><span> YCbCr 4:4:4</span><span>。其中</span><span>YCbCr 4:1:1 </span><span>比较常用，其含义为：每个点保存一个</span><span> 8bit </span><span>的亮度值</span><span>(</span><span>也就是</span><span>Y</span><span>值</span><span>), </span><span>每</span><span> 2x2 </span><span>个点保存一个</span><span> Cr </span><span>和</span><span>Cb </span><span>值</span><span>, </span><span>图像在肉眼中的感觉不会起太大的变化。所以</span><span>, </span><span>原来用</span><span> RGB(R,G,B </span><span>都是</span><span> 8bit unsigned) </span><span>模型</span><span>, 4 </span><span>个点需要</span><span> 8x3=24 bites</span><span>（如下图第一个图）</span><span>. </span><span>而现在仅需要</span><span> 8+(8/4)+(8/4)=12bites, </span><span>平均每个点占</span><span>12bites(</span><span>如下图第二个图</span><span>)</span><span>。这样就把图像的数据压缩了一半。</span><span> </span></p>
<p align=left><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;</span></strong><strong><span>上边仅给出了理论上的示例，在实际数据存储中是有可能是不同的，下面给出几种具体的存储形式：</span></strong><strong><span> </span></strong></p>
<p align=left><span>（</span><span>1</span><span>）</span><span>&nbsp;&nbsp;&nbsp;&nbsp;<strong>YUV 4:4:4</strong> </span></p>
<p align=left><span>YUV</span><span>三个信道的抽样率相同，因此在生成的图像里，每个象素的三个分量信息完整（每个分量通常</span><span>8</span><span>比特），经过</span><span>8</span><span>比特量化之后，未经压缩的每个像素占用</span><span>3</span><span>个字节。</span><span> </span></p>
<p align=left><span>下面的四个像素为</span><span>: [Y<sub>0</sub> U<sub>0</sub> V<sub>0</sub>] [Y<sub>1</sub> U<sub>1</sub> V<sub>1</sub>] [Y<sub>2</sub> U<sub>2</sub> V<sub>2</sub>] [Y<sub>3</sub> U<sub>3</sub> V<sub>3</sub>] </span></p>
<p align=left><span>存放的码流为<span>: Y<sub>0</sub> U<sub>0</sub> V<sub>0</sub> Y<sub>1</sub> U<sub>1</sub> V<sub>1</sub> Y<sub>2</sub> U<sub>2</sub> V<sub>2</sub> Y<sub>3</sub> U<sub>3</sub> V<sub>3</sub></span></span></p>
<p align=left><strong><span>（<span>2</span>）<span>&nbsp;&nbsp; YUV 4:2:2</span></span></strong></p>
<p align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>每个色差信道的抽样率是亮度信道的一半，所以水平方向的色度抽样率只是<span>4:4:4</span>的一半。对非压缩的<span>8</span>比特量化的图像来说，每个由两个水平方向相邻的像素组成的宏像素需要占用<span>4</span>字节内存。</span></p>
<p align=left><span>下面的四个像素为</span><span>: [Y<sub>0</sub> U<sub>0</sub> V<sub>0</sub>] [Y<sub>1</sub> U<sub>1</sub> V<sub>1</sub>] [Y<sub>2</sub> U<sub>2</sub> V<sub>2</sub>] [Y<sub>3</sub> U<sub>3</sub> V<sub>3</sub>] </span></p>
<p align=left><span>存放的码流为<span>: Y<sub>0</sub> U<sub>0</sub> Y<sub>1</sub> V<sub>1</sub> Y<sub>2</sub> U<sub>2</sub> Y<sub>3</sub> V<sub>3</sub></span></span></p>
<p align=left><span>映射出像素点为：<span>[Y<sub>0</sub> U<sub>0</sub> V<sub>1</sub>] [Y<sub>1</sub> U<sub>0</sub> V<sub>1</sub>] [Y<sub>2</sub> U<sub>2</sub> V<sub>3</sub>] [Y<sub>3</sub> U<sub>2</sub> V<sub>3</sub>]<strong></strong></span></span></p>
<p align=left><strong><span>（<span>3</span>）<span>&nbsp;&nbsp; YUV 4:1:1</span></span></strong></p>
<p align=left><span>4:1:1</span><span>的色度抽样，是在水平方向上对色度进行<span>4:1</span>抽样。对于低端用户和消费类产品这仍然是可以接受的。对非压缩的<span>8</span>比特量化的视频来说，每个由<span>4</span>个水平方向相邻的像素组成的宏像素需要占用<span>6</span>字节内存<strong></strong></span></p>
<p align=left><span>下面的四个像素为</span><span>: [Y<sub>0</sub> U<sub>0</sub> V<sub>0</sub>] [Y<sub>1</sub> U<sub>1</sub> V<sub>1</sub>] [Y<sub>2</sub> U<sub>2</sub> V<sub>2</sub>] [Y<sub>3</sub> U<sub>3</sub> V<sub>3</sub>] </span></p>
<p align=left><span>存放的码流为<span>: Y<sub>0</sub> U<sub>0</sub> Y<sub>1</sub> Y<sub>2</sub> V<sub>2</sub> Y<sub>3</sub></span></span></p>
<p align=left><span>映射出像素点为：<span>[Y<sub>0</sub> U<sub>0</sub> V<sub>2</sub>] [Y<sub>1</sub> U<sub>0</sub> V<sub>2</sub>] [Y<sub>2</sub> U<sub>0</sub> V<sub>2</sub>] [Y<sub>3</sub> U<sub>0</sub> V<sub>2</sub>]</span></span></p>
<p align=left><strong><span>（<span>4</span>）<span>YUV4:2:0</span></span></strong></p>
<p align=left><span>&nbsp;&nbsp;&nbsp;&nbsp; 4:2:0</span><span>并不意味着只有<span>Y,Cb</span>而没有<span>Cr</span>分量。它指得是对每行扫描线来说，只有一种色度分量以<span>2:1</span>的抽样率存储。进行隔行扫描，相邻的扫描行存储不同的色度分量，也就是说，如果一行是<span>4:2:0</span>的话，下一行就是<span>4:0:2</span>，再下一行是<span>4:2:0...</span>以此类推。对每个色度分量来说，水平方向和竖直方向的抽样率都是<span>2:1</span>，所以可以说色度的抽样率是<span>4:1</span>。对非压缩的<span>8</span>比特量化的视频来说，每个由<span>2x2</span>个<span>2</span>行<span>2</span>列相邻的像素组成的宏像素需要占用<span>6</span>字节内存。</span></p>
<p align=left><span>下面八个像素为：<span>[Y<sub>0</sub> U<sub>0</sub> V<sub>0</sub>] [Y<sub>1</sub> U<sub>1</sub> V<sub>1</sub>] [Y<sub>2</sub> U<sub>2</sub> V<sub>2</sub>] [Y<sub>3</sub> U<sub>3</sub> V<sub>3</sub>]</span></span></p>
<p align=left><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Y<sub>5</sub> U<sub>5</sub> V<sub>5</sub>] [Y<sub>6</sub> U<sub>6</sub> V<sub>6</sub>] [Y<sub>7</sub>U<sub>7</sub> V<sub>7</sub>] [Y<sub>8</sub> U<sub>8</sub> V<sub>8</sub>]</span></p>
<p align=left><span>存放的码流为：<span>Y<sub>0</sub> U<sub>0</sub> Y<sub>1</sub> Y<sub>2</sub> U<sub>2</sub> Y<sub>3</sub></span></span></p>
<p align=left><sub><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></sub><span>Y<sub>5 </sub>V<sub>5</sub> Y<sub>6</sub> Y<sub>7</sub> V<sub>7</sub> Y<sub>8</sub></span></p>
<p align=left><span>映射出的像素点为：<span>[Y<sub>0</sub> U<sub>0</sub> V<sub>5</sub>] [Y<sub>1</sub> U<sub>0</sub> V<sub>5</sub>] [Y<sub>2</sub> U<sub>2</sub> V<sub>7</sub>] [Y<sub>3</sub> U<sub>2</sub> V<sub>7</sub>]</span></span></p>
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Y<sub>5</sub> U<sub>0</sub> V<sub>5</sub>] [Y<sub>6</sub> U<sub>0</sub> V<sub>5</sub>] [Y<sub>7</sub>U<sub>2</sub> V<sub>7</sub>] [Y<sub>8</sub> U<sub>2</sub> V<sub>7</sub>]</span>&nbsp;<br><br>
<p>对应AVPicture里面有data[4]和linesize[4]其中data是一个指向指针的指针（二级、二维指针），也就是指向视频数据缓冲区的首地址，而data[0]~data[3]是一级指针，可以用如下的图来表示： </p>
<p>data --&gt;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx<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; ^<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; |<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[0]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[1]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[2]<br></p>
<p>比如说，当pix_fmt=PIX_FMT_YUV420P时，data中的数据是按照YUV的格式存储的，也就是： </p>
<pre>data --&gt;YYYYYYYYYYYYYYUUUUUUUUUUUUUVVVVVVVVVVVV
^             ^            ^
|             |            |
data[0]    data[1]      data[2]
</pre>
<p>linesize是指对应于每一行的大小，为什么需要这个变量，是因为在YUV格式和RGB格式时，每行的大小不一定等于图像的宽度，对于RGB格式输出时,只有一个通道(bgrbgrbgr......)可用，即linesize[0],和data[0],so RGB24&nbsp;: data[0] = packet rgb//bgrbgrbgr...... </p>
<pre>linesize[0] = width*3
</pre>
<p>其他的如data[1][2][3]与linesize[1][2][3]无任何意义. </p>
<p>而对于ＹＵＶ格式输出时，有三个通道可用，即data[0][1][2],与linesize[0][1][2]，而yuv格式对于运动估计时，需要填充padding(right, bottom),故： </p>
<pre>linesize=width+padding size(16+16).
///////////////////////////////////////////////////////////////////////////////////////</pre>
<pre><br>&nbsp;&nbsp;&nbsp;case PIX_FMT_YUV420P:<br>&nbsp;&nbsp;&nbsp;case PIX_FMT_YUVJ420P:<br>&nbsp;&nbsp;&nbsp;case PIX_FMT_RGB555:<br>&nbsp;&nbsp;&nbsp;&nbsp;if (PIC_DIRECTION_0 == m_dwFilpPicDirection)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pYuvFrame-&gt;data [0] += m_pYuvFrame-&gt;linesize[0] *&nbsp; m_pVCodecContext-&gt;height;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//因为是隔行扫描U与V只有高度的一半<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pYuvFrame-&gt;data [1] += m_pYuvFrame-&gt;linesize[1] *&nbsp; m_pVCodecContext-&gt;height/2;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pYuvFrame-&gt;data [2] += m_pYuvFrame-&gt;linesize[2] *&nbsp; m_pVCodecContext-&gt;height/2;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pYuvFrame-&gt;linesize[0] = -m_pYuvFrame-&gt;linesize[0];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pYuvFrame-&gt;linesize[1] = -m_pYuvFrame-&gt;linesize[1];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pYuvFrame-&gt;linesize[2] = -m_pYuvFrame-&gt;linesize[2];<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;case PIX_FMT_YUVJ422P:<br>&nbsp;&nbsp;&nbsp;case PIX_FMT_YUV422P:<br>&nbsp;&nbsp;&nbsp;case PIX_FMT_YUYVJ422:<br>&nbsp;&nbsp;&nbsp;case PIX_FMT_YUV411P:<br>&nbsp;&nbsp;&nbsp;case PIX_FMT_YUYV422:&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;if (PIC_DIRECTION_0 == m_dwFilpPicDirection)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pYuvFrame-&gt;data [0] += m_pYuvFrame-&gt;linesize[0] *&nbsp; m_pVCodecContext-&gt;height;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pYuvFrame-&gt;data [1] += m_pYuvFrame-&gt;linesize[1] *&nbsp; m_pVCodecContext-&gt;height;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pYuvFrame-&gt;data [2] += m_pYuvFrame-&gt;linesize[2] *&nbsp; m_pVCodecContext-&gt;height;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pYuvFrame-&gt;linesize[0] = -m_pYuvFrame-&gt;linesize[0];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pYuvFrame-&gt;linesize[1] = -m_pYuvFrame-&gt;linesize[1];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_pYuvFrame-&gt;linesize[2] = -m_pYuvFrame-&gt;linesize[2];<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;}<br>在FFMPEG中转换RGB时顺便颠倒图像的方向算法<br></pre>
</div>
<img src ="http://www.cppblog.com/bangle/aggbug/87070.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/bangle/" target="_blank">黑色天使</a> 2009-06-08 15:23 <a href="http://www.cppblog.com/bangle/archive/2009/06/08/87070.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CEventSocket Beta 1.0</title><link>http://www.cppblog.com/bangle/archive/2008/12/23/70144.html</link><dc:creator>黑色天使</dc:creator><author>黑色天使</author><pubDate>Tue, 23 Dec 2008 05:12:00 GMT</pubDate><guid>http://www.cppblog.com/bangle/archive/2008/12/23/70144.html</guid><wfw:comment>http://www.cppblog.com/bangle/comments/70144.html</wfw:comment><comments>http://www.cppblog.com/bangle/archive/2008/12/23/70144.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/bangle/comments/commentRss/70144.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/bangle/services/trackbacks/70144.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;1#pragma&nbsp;once&nbsp;2&nbsp;3#include&nbsp;&lt;afxmt.h&gt;&nbsp;4#include&nbsp;&lt;map&gt;&nbsp;5&nbsp;6using&nbsp;namespace&nbsp;std;&nbsp;7&nbsp;8#define&nbsp;MAX_PENDING_CONNECTIONS&nbsp;&...&nbsp;&nbsp;<a href='http://www.cppblog.com/bangle/archive/2008/12/23/70144.html'>阅读全文</a><img src ="http://www.cppblog.com/bangle/aggbug/70144.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/bangle/" target="_blank">黑色天使</a> 2008-12-23 13:12 <a href="http://www.cppblog.com/bangle/archive/2008/12/23/70144.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>字符串字串的查找与字符串分割</title><link>http://www.cppblog.com/bangle/archive/2008/12/16/69589.html</link><dc:creator>黑色天使</dc:creator><author>黑色天使</author><pubDate>Tue, 16 Dec 2008 09:34:00 GMT</pubDate><guid>http://www.cppblog.com/bangle/archive/2008/12/16/69589.html</guid><wfw:comment>http://www.cppblog.com/bangle/comments/69589.html</wfw:comment><comments>http://www.cppblog.com/bangle/archive/2008/12/16/69589.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/bangle/comments/commentRss/69589.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/bangle/services/trackbacks/69589.html</trackback:ping><description><![CDATA[<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"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;ExtractString(CStringArray</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;arr,&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;CString&nbsp;strSrc,&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;TCHAR&nbsp;sep&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br><img id=Codehighlighter1_83_347_Open_Image onclick="this.style.display='none'; Codehighlighter1_83_347_Open_Text.style.display='none'; Codehighlighter1_83_347_Closed_Image.style.display='inline'; Codehighlighter1_83_347_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_83_347_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_83_347_Closed_Text.style.display='none'; Codehighlighter1_83_347_Open_Image.style.display='inline'; Codehighlighter1_83_347_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_83_347_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"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_83_347_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;CString&nbsp;str(strSrc);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;str.TrimLeft();&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;str.TrimRight();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(str.IsEmpty())<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;pos&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;str.Find(sep);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;(pos&nbsp;</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)<br><img id=Codehighlighter1_220_298_Open_Image onclick="this.style.display='none'; Codehighlighter1_220_298_Open_Text.style.display='none'; Codehighlighter1_220_298_Closed_Image.style.display='inline'; Codehighlighter1_220_298_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_220_298_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_220_298_Closed_Text.style.display='none'; Codehighlighter1_220_298_Open_Image.style.display='inline'; Codehighlighter1_220_298_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_220_298_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"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_220_298_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arr.Add(str.Left(pos));<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;str.Mid(pos&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pos&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;str.Find(sep);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(strcmp(str,&nbsp;_T(</span><span style="COLOR: #000000">""</span><span style="COLOR: #000000">))&nbsp;</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arr.Add(str);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<br><br><br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;StrIndex(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">str,&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">substr)<br><img id=Codehighlighter1_50_349_Open_Image onclick="this.style.display='none'; Codehighlighter1_50_349_Open_Text.style.display='none'; Codehighlighter1_50_349_Closed_Image.style.display='inline'; Codehighlighter1_50_349_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_50_349_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_50_349_Closed_Text.style.display='none'; Codehighlighter1_50_349_Open_Image.style.display='inline'; Codehighlighter1_50_349_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_50_349_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"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_50_349_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img id=Codehighlighter1_96_109_Open_Image onclick="this.style.display='none'; Codehighlighter1_96_109_Open_Text.style.display='none'; Codehighlighter1_96_109_Closed_Image.style.display='inline'; Codehighlighter1_96_109_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_96_109_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_96_109_Closed_Text.style.display='none'; Codehighlighter1_96_109_Open_Image.style.display='inline'; Codehighlighter1_96_109_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;nEnd&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;strlen(str)&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;strlen(substr);&nbsp;&nbsp;</span><span id=Codehighlighter1_96_109_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=Codehighlighter1_96_109_Open_Text><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">&nbsp;计算结束位置&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img id=Codehighlighter1_151_165_Open_Image onclick="this.style.display='none'; Codehighlighter1_151_165_Open_Text.style.display='none'; Codehighlighter1_151_165_Closed_Image.style.display='inline'; Codehighlighter1_151_165_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_151_165_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_151_165_Closed_Text.style.display='none'; Codehighlighter1_151_165_Open_Image.style.display='inline'; Codehighlighter1_151_165_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(&nbsp;nEnd&nbsp;</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</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;</span><span id=Codehighlighter1_151_165_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=Codehighlighter1_151_165_Open_Text><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">&nbsp;子字符串小于字符串&nbsp;</span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br><img id=Codehighlighter1_168_334_Open_Image onclick="this.style.display='none'; Codehighlighter1_168_334_Open_Text.style.display='none'; Codehighlighter1_168_334_Closed_Image.style.display='inline'; Codehighlighter1_168_334_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_168_334_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_168_334_Closed_Text.style.display='none'; Codehighlighter1_168_334_Open_Image.style.display='inline'; Codehighlighter1_168_334_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_168_334_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"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_168_334_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000">&nbsp;nEnd;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">&nbsp;)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;j&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;i;&nbsp;str[j]&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;substr[j</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">i];&nbsp;j</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">&nbsp;)<br><img id=Codehighlighter1_287_301_Open_Image onclick="this.style.display='none'; Codehighlighter1_287_301_Open_Text.style.display='none'; Codehighlighter1_287_301_Closed_Image.style.display='inline'; Codehighlighter1_287_301_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_287_301_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_287_301_Closed_Text.style.display='none'; Codehighlighter1_287_301_Open_Image.style.display='inline'; Codehighlighter1_287_301_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(&nbsp;substr[j</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">i</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">\0</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">&nbsp;)&nbsp;</span><span id=Codehighlighter1_287_301_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=Codehighlighter1_287_301_Open_Text><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">&nbsp;子字符串字结束&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&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: #000000">1</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<img src ="http://www.cppblog.com/bangle/aggbug/69589.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/bangle/" target="_blank">黑色天使</a> 2008-12-16 17:34 <a href="http://www.cppblog.com/bangle/archive/2008/12/16/69589.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>两种单件模式</title><link>http://www.cppblog.com/bangle/archive/2008/11/11/66617.html</link><dc:creator>黑色天使</dc:creator><author>黑色天使</author><pubDate>Tue, 11 Nov 2008 08:58:00 GMT</pubDate><guid>http://www.cppblog.com/bangle/archive/2008/11/11/66617.html</guid><wfw:comment>http://www.cppblog.com/bangle/comments/66617.html</wfw:comment><comments>http://www.cppblog.com/bangle/archive/2008/11/11/66617.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/bangle/comments/commentRss/66617.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/bangle/services/trackbacks/66617.html</trackback:ping><description><![CDATA[
<div style="padding-right: 5px; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"><span style="COLOR: #008000">//</span><span style="COLOR: #008000">适合于比较小的对象</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&#160;CSingletonObj<br><img id="Codehighlighter1_32_266_Open_Image" onclick="this.style.display='none'; Codehighlighter1_32_266_Open_Text.style.display='none'; Codehighlighter1_32_266_Closed_Image.style.display='inline'; Codehighlighter1_32_266_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img id="Codehighlighter1_32_266_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_32_266_Closed_Text.style.display='none'; Codehighlighter1_32_266_Open_Image.style.display='inline'; Codehighlighter1_32_266_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align="top"></span><span id="Codehighlighter1_32_266_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"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id="Codehighlighter1_32_266_Open_Text"><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top">&#160;&#160;&#160;&#160;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&#160;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">CSingletonObj(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">);&#160;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">必须为公有</span><span style="COLOR: #008000"><br><img id="Codehighlighter1_119_138_Open_Image" onclick="this.style.display='none'; Codehighlighter1_119_138_Open_Text.style.display='none'; Codehighlighter1_119_138_Closed_Image.style.display='inline'; Codehighlighter1_119_138_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_119_138_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_119_138_Closed_Text.style.display='none'; Codehighlighter1_119_138_Open_Image.style.display='inline'; Codehighlighter1_119_138_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align="top"></span><span style="COLOR: #000000">&#160;&#160;&#160;&#160;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&#160;CSingletonObj</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&#160;Instance(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)&#160;</span><span id="Codehighlighter1_119_138_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"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id="Codehighlighter1_119_138_Open_Text"><span style="COLOR: #000000">{</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&#160;m_Instance;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"></span><span style="COLOR: #0000ff">protected</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top">&#160;&#160;&#160;&#160;CSingletonObj(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">);&#160;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">防止构造与拷贝</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"></span><span style="COLOR: #000000">&#160;&#160;&#160;&#160;CSingletonObj(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&#160;CSingletonObj</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top">&#160;&#160;&#160;&#160;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&#160;CSingletonObj&#160;m_Instance;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top">}</span></span><span style="COLOR: #000000">;</span></div>
<div style="padding-right: 5px; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><span style="COLOR: #000000"><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">#include &lt;memory></div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><br></div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">using namespace std;</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><br></div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">template&lt;class &#160;T></div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">class Singleton</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">{</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">public:</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><span class="Apple-tab-span" style="white-space:pre">	</span>static T* GetInstance();</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><br></div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">protected:</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><span class="Apple-tab-span" style="white-space:pre">	</span>Singleton(void) {}</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><span class="Apple-tab-span" style="white-space:pre">	</span>~Singleton(void) {}</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><span class="Apple-tab-span" style="white-space:pre">	</span>Singleton(const Singleton&amp;) {}</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><span class="Apple-tab-span" style="white-space:pre">	</span>Singleton &amp; operator = (const Singleton&amp;) {}</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><br></div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">private:</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><span class="Apple-tab-span" style="white-space:pre">	</span>static auto_ptr&lt;T> _instance;</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">};</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><br></div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><br></div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">template &lt;class T></div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">auto_ptr&lt;T> Singleton&lt;T>::_instance;</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><br></div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">template &lt;class T></div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">inline T* Singleton&lt;T>::GetInstance()</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">{</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><span class="Apple-tab-span" style="white-space:pre">	</span>if( 0 == _instance.get())</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><span class="Apple-tab-span" style="white-space:pre">	</span>{</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><span class="Apple-tab-span" style="white-space:pre">		</span>// 加入临界区，可实现多线程安全</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><span class="Apple-tab-span" style="white-space:pre">		</span>_instance.reset ( new T);</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><span class="Apple-tab-span" style="white-space:pre">	</span>}</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><br></div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><span class="Apple-tab-span" style="white-space:pre">	</span>return _instance.get();</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">}</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">//////////////////////////////////////////////////////////////////////////</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">//使用</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">class Test : public Singleton&lt;Test>&#160;</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">{&#160;</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">public:&#160;</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><span class="Apple-tab-span" style="white-space:pre">	</span>void foo();&#160;</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">private:&#160;</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><span class="Apple-tab-span" style="white-space:pre">	</span>Test();&#160;</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><span class="Apple-tab-span" style="white-space:pre">	</span>~Test();&#160;</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); "><span class="Apple-tab-span" style="white-space:pre">	</span>friend class Singleton&lt;Test>;&#160;</div><div style="padding-right: 5px; padding-left: 4px; padding-bottom: 4px; border-left-color: rgb(204, 204, 204); width: 98%; word-break: break-all; padding-top: 4px; background-color: rgb(238, 238, 238); ">};&#160;</div></span></div><img src ="http://www.cppblog.com/bangle/aggbug/66617.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/bangle/" target="_blank">黑色天使</a> 2008-11-11 16:58 <a href="http://www.cppblog.com/bangle/archive/2008/11/11/66617.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>memcpy的BUG</title><link>http://www.cppblog.com/bangle/archive/2008/10/15/64008.html</link><dc:creator>黑色天使</dc:creator><author>黑色天使</author><pubDate>Wed, 15 Oct 2008 02:31:00 GMT</pubDate><guid>http://www.cppblog.com/bangle/archive/2008/10/15/64008.html</guid><wfw:comment>http://www.cppblog.com/bangle/comments/64008.html</wfw:comment><comments>http://www.cppblog.com/bangle/archive/2008/10/15/64008.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/bangle/comments/commentRss/64008.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/bangle/services/trackbacks/64008.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: If   the   source   and   destination   overlap,   memcpy   does   not   ensure   that   the   original   source   bytes   in   the   overlapping   region   are   copied   before   being   overwritten.   Use   memmove   to   handle   overlapping   regions   <br>  如果原始资料source和目的单元格destination（的地址）重复了。在重复区域的原始source的字节被覆盖以前，memcpy不能保证这些区域被拷贝。使用memove来处理重复的区域。&nbsp;&nbsp;<a href='http://www.cppblog.com/bangle/archive/2008/10/15/64008.html'>阅读全文</a><img src ="http://www.cppblog.com/bangle/aggbug/64008.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/bangle/" target="_blank">黑色天使</a> 2008-10-15 10:31 <a href="http://www.cppblog.com/bangle/archive/2008/10/15/64008.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>尽量使用C++风格的类型转换</title><link>http://www.cppblog.com/bangle/archive/2008/09/28/62984.html</link><dc:creator>黑色天使</dc:creator><author>黑色天使</author><pubDate>Sun, 28 Sep 2008 07:12:00 GMT</pubDate><guid>http://www.cppblog.com/bangle/archive/2008/09/28/62984.html</guid><wfw:comment>http://www.cppblog.com/bangle/comments/62984.html</wfw:comment><comments>http://www.cppblog.com/bangle/archive/2008/09/28/62984.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/bangle/comments/commentRss/62984.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/bangle/services/trackbacks/62984.html</trackback:ping><description><![CDATA[<span style="font-family: ����; font-size: 12px; ">&#160;&#160;仔细想想地位卑贱的类型转换功能（cast），其在程序设计中的地位就象goto语句一样令人鄙视。但是它还不是无法令人忍受，因为当在某些紧要的关头，类型转换还是必需的，这时它是一个必需品。 &#160;&#160;<br>&#160; 不过C风格的类型转换并不代表所有的类型转换功能。 &#160;&#160;<br>&#160; 一来它们过于粗鲁，能允许你在任何类型之间进行转换。不过如果要进行更精确的类型转换，这会是一个优点。在这些类型转换中存在着巨大的不同，例如把一个指向const对象的指针（pointer-to-const-object）转换成指向非const对象的指针（pointer-to-non-const-object）(即一个仅仅去除const的类型转换)，把一个指向基类的指针转换成指向子类的指针（即完全改变对象类型）。传统的C风格的类型转换不对上述两种转换进行区分。（这一点也不令人惊讶，因为C风格的类型转换是为C语言设计的，而不是为C++语言设计的）。 &#160;&#160;<br>&#160; 二来C风格的类型转换在程序语句中难以识别。在语法上，类型转换由圆括号和标识符组成，而这些可以用在C＋＋中的任何地方。这使得回答象这样一个最基本的有关类型转换的问题变得很困难：&#8220;在这个程序中是否使用了类型转换？&#8221;。这是因为人工阅读很可能忽略了类型转换的语句，而利用象grep的工具程序也不能从语句构成上区分出它们来。 &#160;&#160;<br>&#160; C++通过引进四个新的类型转换操作符克服了C风格类型转换的缺点，这四个操作符是, &#160; static_cast, &#160; const_cast, &#160; dynamic_cast, &#160; 和reinterpret_cast。在大多数情况下，对于这些操作符你只需要知道原来你习惯于这样写， &#160;&#160;<br>&#160; (type) &#160; expression &#160;&#160;<br>&#160; 而现在你总应该这样写： &#160;&#160;<br>&#160; static_cast&lt;type>(expression) &#160;&#160;<br>&#160; 例如，假设你想把一个int转换成double，以便让包含int类型变量的表达式产生出浮点数值的结果。如果用C风格的类型转换，你能这样写： &#160;&#160;<br>&#160; int &#160; firstNumber, &#160; secondNumber; &#160;&#160;<br>&#160; ... &#160;&#160;<br>&#160; double &#160; result &#160; = &#160; ((double)firstNumber)/secondNumber； &#160;&#160;<br>&#160; 如果用上述新的类型转换方法，你应该这样写： &#160;&#160;<br>&#160; double &#160; result &#160; = &#160; static_cast&lt;double>(firstNumber)/secondNumber; &#160;&#160;<br>&#160; 这样的类型转换不论是对人工还是对程序都很容易识别。 &#160;&#160;<br>&#160; static_cast在功能上基本上与C风格的类型转换一样强大，含义也一样。它也有功能上限制。例如，你不能用static_cast象用C风格的类型转换一样把struct转换成int类型或者把double类型转换成指针类型，另外，static_cast不能从表达式中去除const属性，因为另一个新的类型转换操作符const_cast有这样的功能。 &#160;<br>&#160; 其它新的C++类型转换操作符被用在需要更多限制的地方。const_cast用于类型转换掉表达式的const或volatileness属性。通过使用const_cast，你向人们和编译器强调你通过类型转换想做的只是改变一些东西的constness或者 &#160; volatileness属性。这个含义被编译器所约束。如果你试图使用const_cast来完成修改constness &#160; 或者volatileness属性之外的事情，你的类型转换将被拒绝。下面是一些例子： &#160;&#160;<br>&#160; class &#160; Widget &#160; { &#160; ... &#160; }; &#160;&#160;<br>&#160; class &#160; SpecialWidget: &#160; public &#160; Widget &#160; { &#160; ... &#160; }; &#160;&#160;<br>&#160; void &#160; update(SpecialWidget &#160; *psw); &#160;&#160;<br>&#160; SpecialWidget &#160; sw; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // &#160; sw &#160; 是一个非const &#160; 对象。 &#160;&#160;<br>&#160; const &#160; SpecialWidget&amp; &#160; csw &#160; = &#160; sw; &#160; &#160; &#160; // &#160; csw &#160; 是sw的一个引用 &#160;&#160;<br>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // &#160; 它是一个const &#160; 对象 &#160; &#160;&#160;<br>&#160; update(&amp;csw); &#160; &#160; // &#160; 错误!不能传递一个const &#160; SpecialWidget* &#160; 变量 &#160;&#160;<br>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // &#160; 给一个处理SpecialWidget*类型变量的函数 &#160; &#160;&#160;<br>&#160; update(const_cast&lt;SpecialWidget*>(&amp;csw)); &#160;&#160;<br>&#160; // &#160; 正确，csw的const被显示地转换掉（ &#160;&#160;<br>&#160; // &#160; csw和sw两个变量值在update &#160;&#160;<br>&#160; //函数中能被更新） &#160; &#160;&#160;<br>&#160; update((SpecialWidget*)&amp;csw); &#160;&#160;<br>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // &#160; 同上，但用了一个更难识别 &#160;&#160;<br>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; //的C风格的类型转换 &#160;&#160;<br>&#160; Widget &#160; *pw &#160; = &#160; new &#160; SpecialWidget; &#160; &#160;&#160;<br>&#160; update(pw); &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // &#160; 错误！pw的类型是Widget*，但是 &#160;&#160;<br>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // &#160; update函数处理的是SpecialWidget*类型 &#160; &#160;&#160;<br>&#160; update(const_cast&lt;SpecialWidget*>(pw)); &#160;&#160;<br>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // &#160; 错误！const_cast仅能被用在影响 &#160;&#160;<br>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // &#160; constness &#160; or &#160; volatileness的地方上。, &#160;&#160;<br>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // &#160; 不能用在向继承子类进行类型转换。 &#160;&#160;<br>&#160; 到目前为止，const_cast最普通的用途就是转换掉对象的const属性。 &#160;&#160;<br>&#160; 第二种特殊的类型转换符是dynamic_cast，它被用于安全地沿着类的继承关系向下进行类型转换。这就是说，你能用dynamic_cast把指向基类的指针或引用转换成指向其派生类或其兄弟类的指针或引用，而且你能知道转换是否成功。失败的转换将返回空指针（当对指针进行类型转换时）或者抛出异常（当对引用进行类型转换时）： &#160;&#160;<br>&#160; Widget &#160; *pw; &#160;&#160;<br>&#160; ... &#160;&#160;<br>&#160; update(dynamic_cast&lt;SpecialWidget*>(pw)); &#160;&#160;<br>&#160; // &#160; 正确，传递给update函数一个指针 &#160;&#160;<br>&#160; // &#160; 是指向变量类型为SpecialWidget的pw的指针 &#160;&#160;<br>&#160; // &#160; 如果pw确实指向一个对象, &#160;&#160;<br>&#160; // &#160; 否则传递过去的将使空指针。 &#160;&#160;<br>&#160; void &#160; updateViaRef(SpecialWidget&amp; &#160; rsw); &#160;&#160;<br>&#160; updateViaRef(dynamic_cast&lt;SpecialWidget&amp;>(*pw)); &#160;&#160;<br>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; //正确。 &#160; 传递给updateViaRef函数 &#160;&#160;<br>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // &#160; SpecialWidget &#160; pw &#160; 指针，如果pw &#160; &#160;&#160;<br>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // &#160; 确实指向了某个对象 &#160;&#160;<br>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // &#160; 否则将抛出异常 &#160;&#160;<br>&#160; dynamic_casts在帮助你浏览继承层次上是有限制的。它不能被用于没有虚函数的类型上，因为他要得到类的运行时信息，这个多保存于Vtablez中，也不能用它来转换掉constness： &#160;&#160;<br>&#160; int &#160; firstNumber, &#160; secondNumber; &#160;&#160;<br>&#160; ... &#160;&#160;<br>&#160; double &#160; result &#160; = &#160; dynamic_cast&lt;double>(firstNumber)/secondNumber; &#160;&#160;<br>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // &#160; 错误！没有继承关系 &#160;&#160;<br>&#160; const &#160; SpecialWidget &#160; sw; &#160;&#160;<br>&#160; ... &#160;&#160;<br>&#160; update(dynamic_cast&lt;SpecialWidget*>(&amp;sw)); &#160;&#160;<br>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // &#160; 错误! &#160; dynamic_cast不能转换 &#160;&#160;<br>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // &#160; 掉const。 &#160;&#160;<br>&#160; 如你想在没有继承关系的类型中进行转换，你可能想到static_cast。如果是为了去除const，你总得用const_cast。 &#160;&#160;<br>&#160; 这四个类型转换符中的最后一个是reinterpret_cast。使用这个操作符的类型转换，其的转换结果几乎都是执行期定义（implementation-defined）。因此，使用reinterpret_casts的代码很难移植。 &#160;&#160;<br>&#160; reinterpret_casts的最普通的用途就是在函数指针类型之间进行转换。例如，假设你有一个函数指针数组： &#160;<br>&#160; typedef &#160; void &#160; (*FuncPtr)(); &#160; &#160; &#160; &#160; &#160; &#160; // &#160; FuncPtr &#160; is &#160; 一个指向函数 &#160;&#160;<br>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // &#160; 的指针，该函数没有参数 &#160;&#160;<br>&#160; // &#160; 返回值类型为void &#160;&#160;<br>&#160; FuncPtr &#160; funcPtrArray[10]; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // &#160; funcPtrArray &#160; 是一个能容纳 &#160;&#160;<br>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // &#160; 10个FuncPtrs指针的数组 &#160;&#160;<br>&#160; 让我们假设你希望（因为某些莫名其妙的原因）把一个指向下面函数的指针存入funcPtrArray数组： &#160;&#160;<br>&#160; int &#160; doSomething(); &#160;&#160;<br>&#160; 你不能不经过类型转换而直接去做，因为doSomething函数对于funcPtrArray数组来说有一个错误的类型。在FuncPtrArray数组里的函数返回值是void类型，而doSomething函数返回值是int类型。 &#160;&#160;<br>&#160; funcPtrArray[0] &#160; = &#160; &amp;doSomething; &#160; &#160; &#160; &#160; &#160; // &#160; 错误！类型不匹配 &#160; &#160;&#160;<br>&#160; reinterpret_cast可以让你迫使编译器以你的方法去看待它们： &#160;&#160;<br>&#160; funcPtrArray[0] &#160; = &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; // &#160; this &#160; compiles &#160;&#160;<br>&#160; &#160; &#160; reinterpret_cast&lt;FuncPtr>(&amp;doSomething); &#160;&#160;<br>&#160; 转换函数指针的代码是不可移植的（C++不保证所有的函数指针都被用一样的方法表示），在一些情况下这样的转换会产生不正确的结果（参见条款M31），所以你应该避免转换函数指针类型，除非你处于着背水一战和尖刀架喉的危急时刻。一把锋利的刀。一把非常锋利的刀。 &#160;&#160;<br>&#160; 如果你使用的编译器缺乏对新的类型转换方式的支持，你可以用传统的类型转换方法代替static_cast, &#160; const_cast, &#160; 以及reinterpret_cast。也可以用下面的宏替换来模拟新的类型转换语法： &#160;&#160;<br>&#160; #define &#160; static_cast(TYPE,EXPR) &#160; &#160; &#160; &#160; &#160; &#160; &#160; ((TYPE)(EXPR)) &#160;&#160;<br>&#160; #define &#160; const_cast(TYPE,EXPR) &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; ((TYPE)(EXPR)) &#160;&#160;<br>&#160; #define &#160; reinterpret_cast(TYPE,EXPR) &#160; &#160; ((TYPE)(EXPR)) &#160;&#160;<br>&#160; 你可以象这样使用使用： &#160;&#160;<br>&#160; double &#160; result &#160; = &#160; static_cast(double, &#160; firstNumber)/secondNumber; &#160;&#160;<br>&#160; update(const_cast(SpecialWidget*, &#160; &amp;sw)); &#160;&#160;<br>&#160; funcPtrArray[0] &#160; = &#160; reinterpret_cast(FuncPtr, &#160; &amp;doSomething); &#160;&#160;<br>&#160; 这些模拟不会象真实的操作符一样安全，但是当你的编译器可以支持新的的类型转换时，它们可以简化你把代码升级的过程。 &#160;&#160;<br>&#160; 没有一个容易的方法来模拟dynamic_cast的操作，但是很多函数库提供了函数，安全地在派生类与基类之间进行类型转换。如果你没有这些函数而你有必须进行这样的类型转换，你也可以回到C风格的类型转换方法上，但是这样的话你将不能获知类型转换是否失败。当然，你也可以定义一个宏来模拟dynamic_cast的功能，就象模拟其它的类型转换一样： &#160;&#160;<br>&#160; #define &#160; dynamic_cast(TYPE,EXPR) &#160; &#160; &#160; &#160; &#160; (TYPE)(EXPR) &#160;&#160;<br>&#160; 请记住，这个模拟并不能完全实现dynamic_cast的功能，它没有办法知道转换是否失败。 &#160;&#160;<br>&#160; 我知道，是的，我知道，新的类型转换操作符不是很美观而且用键盘键入也很麻烦。如果你发现它们看上去实在令人讨厌，C风格的类型转换还可以继续使用并且合法。然而，正是因为新的类型转换符缺乏美感才能使它弥补了在含义精确性和可辨认性上的缺点。并且，使用新类型转换符的程序更容易被解析（不论是对人工还是对于工具程序），它们允许编译器检测出原来不能发现的错误。这些都是放弃C风格类型转换方法的强有力的理由。还有第三个理由：也许让类型转换符不美观和键入麻烦是一件好事。 &#160;&#160;<br></span><img src ="http://www.cppblog.com/bangle/aggbug/62984.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/bangle/" target="_blank">黑色天使</a> 2008-09-28 15:12 <a href="http://www.cppblog.com/bangle/archive/2008/09/28/62984.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>理解复杂的C++声明</title><link>http://www.cppblog.com/bangle/archive/2008/08/22/59624.html</link><dc:creator>黑色天使</dc:creator><author>黑色天使</author><pubDate>Fri, 22 Aug 2008 02:44:00 GMT</pubDate><guid>http://www.cppblog.com/bangle/archive/2008/08/22/59624.html</guid><wfw:comment>http://www.cppblog.com/bangle/comments/59624.html</wfw:comment><comments>http://www.cppblog.com/bangle/archive/2008/08/22/59624.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/bangle/comments/commentRss/59624.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/bangle/services/trackbacks/59624.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/bangle/archive/2008/08/22/59624.html'>阅读全文</a><img src ="http://www.cppblog.com/bangle/aggbug/59624.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/bangle/" target="_blank">黑色天使</a> 2008-08-22 10:44 <a href="http://www.cppblog.com/bangle/archive/2008/08/22/59624.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>