﻿<?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++博客-deepway-文章分类-C++ 语言</title><link>http://www.cppblog.com/maxime/category/14143.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 04 Aug 2010 07:13:10 GMT</lastBuildDate><pubDate>Wed, 04 Aug 2010 07:13:10 GMT</pubDate><ttl>60</ttl><item><title>C++ 对象作用域</title><link>http://www.cppblog.com/maxime/articles/122094.html</link><dc:creator>maxime</dc:creator><author>maxime</author><pubDate>Tue, 03 Aug 2010 11:23:00 GMT</pubDate><guid>http://www.cppblog.com/maxime/articles/122094.html</guid><wfw:comment>http://www.cppblog.com/maxime/comments/122094.html</wfw:comment><comments>http://www.cppblog.com/maxime/articles/122094.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/maxime/comments/commentRss/122094.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/maxime/services/trackbacks/122094.html</trackback:ping><description><![CDATA[<p><br>看了会glog使用文档，很快就被下面的语法形式吸引了，这颗语法糖，真是太完美了。&nbsp;</p>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LOG(INFO)&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Found&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;num_cookies&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;cookies</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">2</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CHECK(fp</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">Write(x)&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">)&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Write&nbsp;failed!</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">3</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span></div>
<br>符号&#8220;&lt;&lt;&#8221;，第一眼就能理解，使用了流对象重载操作符&#8220;&lt;&lt;&#8221;的方法。<br><br>问题是，如果LOG(INFO)实际上是一个流对象的话，那它怎么做到&#8220;在禁止输出日志时不编译&#8220;&lt;&lt;&#8221;右边的代码&#8221;呢？<br><br>要知道LOG4cpplus，可以是用了下面的语法结构才实现的，依靠最后那个括号。glog的语法显然更胜一筹了。<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><span style="COLOR: #000000">LOG(INFO，</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Found</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;num_cookies&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;cookies</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);&nbsp;</span></div>
<br>于是，跟踪代码，总于一窥真面目，大为感叹。翻译成原始代码，应该这样的，<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><span style="COLOR: #000000">LogMessage().stream()&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Found&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;num_cookies&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;cookies</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;</span></div>
巧妙之处，就在于LogMessage是一个类，LogMessage()生成了一个临时局部对象，它的生命期仅在这一行代码范围内。<br>就是说，这行结束的时候，LogMessage就被析构，在析构函数中，去执行真正的日志输出。<br><br><br>写上面例子，是为了引出本文真正的主题，利用C++对象的生命期来实现特殊代码控制流程。<br><br>早年，学习Basic语言的时候，听老师说了结构化编程中流程控制的三大元素&#8220;顺序、选择、循环&#8221;，真以为有了三大元素，便无所不能了，其他的都是多余的。<br><br>但实际上，一个例外便是：在一个作用域开始时，执行一些代码；在作用域退出时，执行另一些代码。比如，Win32上的句柄管理，获取了句柄，最后一定要释放。<br><br>我个人认为，这种流程控制，在现代C++编程中是如此重要，为其提供专门语法机制毫不为过。<br><br>然而，C++前辈们用一种可说巧妙，也可卑劣的方式，来处理这个问题，即利用对象在作用域中的构造与析构。<br><br>说它卑劣，是因为如此重要的特性，在C++教材里是找不到，使它得不到应有的重视。<br><br>当然不管怎么说，这个特性是C++优于C的极少特例之一。<br><br><br>总结一下，我们可以在四种对象作用范围内，实现上述的特殊流程控制：<br><br>1. 全局对象生命期。一般不推荐使用全局变量，没有多少实际意义；<br>2. 类成员变量，即类生命期。最典型的就是智能指针了。<br>3.局部变量，即函数中的块作用域。这是最普遍的，比如什么互斥量守护，资源句柄守护等等。<br>4.局部匿名变量（不知道是否该这样命名），在代码行的作用域。这很少见，glog算是见到的第一个了。<br><br><br><br>
<img src ="http://www.cppblog.com/maxime/aggbug/122094.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/maxime/" target="_blank">maxime</a> 2010-08-03 19:23 <a href="http://www.cppblog.com/maxime/articles/122094.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>