﻿<?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++博客-Randy</title><link>http://www.cppblog.com/Randy/</link><description>人之所以痛苦，在于追求错误的东西</description><language>zh-cn</language><lastBuildDate>Tue, 07 Apr 2026 04:26:48 GMT</lastBuildDate><pubDate>Tue, 07 Apr 2026 04:26:48 GMT</pubDate><ttl>60</ttl><item><title>c++之父之一席之谈(也许是笑话，但不要仅仅当成笑话)</title><link>http://www.cppblog.com/Randy/archive/2009/11/01/99939.html</link><dc:creator>Randy</dc:creator><author>Randy</author><pubDate>Sun, 01 Nov 2009 06:08:00 GMT</pubDate><guid>http://www.cppblog.com/Randy/archive/2009/11/01/99939.html</guid><wfw:comment>http://www.cppblog.com/Randy/comments/99939.html</wfw:comment><comments>http://www.cppblog.com/Randy/archive/2009/11/01/99939.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/Randy/comments/commentRss/99939.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Randy/services/trackbacks/99939.html</trackback:ping><description><![CDATA[在1998年的元旦，Bjarne Stroustrup（C++之父）接受了IEEE《计算机》杂志记者的专访。编辑很自然的认为他会对于过去七年来使用他创建的语言进行面对对象设计做一个历史性的回顾。而在这个专访中，记者获得了更有价值的新闻，但是最后编辑决定为了整个IT产业，这个稿子不能发表，但是就像其它被砍掉的新闻，往往还是弄得路人皆知的。<br>这一篇适当时专访的完全拷贝，没有被编辑、删改或者做过什么润色处理，也没有发布过，可能看起来不像常见的杂志文章，但这是实情。 <br><br>你会发现真正引人入胜的地方... ... <br><br>记者: 您在几年前你改变了软件设计世界的面貌，现在再回首往事您有什么感想？ <br><br>Stroustrup: 事实上我在你到来之前的这些天里一直在考虑这件事，你还记得几乎所有的人都在写 C程序那会儿吗？麻烦的是这些人写得太好了，而且那些个大学也都在努力的传授 C编程技术。的确他们是十分的成功——我要特别的指出"成功"这个词——因为这种显著的 C程序员的培养效率，这就是产生问题的原因。 <br><br>记者: 这难道是个问题吗？ <br><br>Stroustrup: 当然，你记得大家都在用Cobol语言写程序的时候吗？ <br><br>记者: 哦，当然，当时我也一样。 <br><br>Stroustrup: 在一开始的时候，这些人简直象半个上帝似的拿着高工资，享受着贵族一样的待遇。 <br><br>记者: 唉，那些日子多么的让人怀念，是吧？ <br><br>Stroustrup: 当然了。但是接着发生了什么？IBM觉得这样不舒服，就投资了数百万来培养程序员，直到程序员多得一毛钱就可以雇一打。 <br><br>记者: 这就是为什么当时我撤出来了，工资在一年里就降到人们在说做个记者都比程序员强的地步。 <br><br>Stroustrup: 对啦！那时侯相同的事情发生在了C程序员身上了。 <br><br>记者: 这个我明白了，可是您要说的是...... <br><br>Stroustrup: 有一天，我坐在办公室里就在想如何能把这件事挽回一些。我想知道如果有一种特别复杂而且难以学会的语言，是否就没有人可以又把程序员们搞到市场的泥潭里去呢？我用了从X10里了解到的东西，，噢，就是X-Windows，真是一个该死的图形系统，只能运行在那些个SUN 3/60的机器里，哈！它具有所有我想要的特征：可笑而复杂的语法，含混的功能描述，还有伪装的OO结构，就算是在现在，还是没有人愿意用那些东西，如果你不想发疯的话，Motif才是唯一解决方案。 <br><br>记者: 你是在开玩笑吗? <br><br>Stroustrup: 没有，事实上还有另外的一个问题，UNIX是用C写的，就是说任何一个C程序员都可以很容易的成为系统程序的开发者。还记得一个大型的主机系统应用的开发者通常能挣多少钱吗？ <br><br>记者: 你肯定是知道我当时就是干这个的。 <br><br>Stroustrup: 好吧，因此这个新的语言一定要通过隐藏所有的系统调用来和UNIX分离开来，这样可以使那些个就只是知道DOS的人也可以活得很体面。 <br><br>记者: 我不大相信您说的这个...... <br><br>Stroustrup: 而且到现在时间也够长的了，我相信有很多的人已经指出了C++是对时间的浪费，我要说的是，这个过程比我想象的要长的多了。 <br><br>记者: 那么您又是如何做到的呢？ <br><br>Stroustrup: 那只是一个玩笑，我真的没有想到人们会对那本书那么认真。任何人只要长了半个大脑也应该明白面对对象编程是荒谬而不合逻辑的，而且效率低下。 <br><br>记者: 什么？ <br><br>Stroustrup: 再说代码重用，你什么时候听说过有公司重用他的代码？ <br><br>记者: 事实上从来没有，但是...... <br><br>Stroustrup: 那么我提醒你一下，在早期有很多的例子。哦，有一家叫Menter Graphics的俄勒冈州公司，我认为他们应该是感冒了，竟然在90年或者是91年把所有的代码用C++重写了一遍，对不起，我实在是想不起确切的时间了，我看大家应该从这个事件中吸取教训。 <br><br>记者: 没有人真正的吸取了教训吗？ <br><br>Stroustrup: <br><br>没有，而且还有很多公司犯同样的错误，还向他们的股东解释说那3亿美圆的损失是正常的，他们就是做了这样的事情。 <br><br>记者: 真的？可是这也只能证明OO方法是能够工作的，不是吗？ <br><br>Stroustrup: 也许吧，执行文件是那么大，在一台有128M内存的HP工作站上只是装载到内存中就要用5分钟时间，然后将象毛毛虫爬树一样的运行。事实上我在第一个礼拜就发现了这个缺点，奇怪的是好象没人在乎这个，Sun和HP好象只在乎买出那些功能强大的各种玩意儿，而不在乎在上面跑什么程序。在AT&amp;.T的时候我编了一个"Hello World"程序，简直是难以置信，执行文件有2.1M。 <br><br>记者: 那么大？是啊，就是从那时候开始的编译程序产生大个的文件的。 <br><br>Stroustrup: 就是这个样子，如果你不信的话，可以用最新版的g++试一下，你得到的东西不会小于0.5M，而且就在最近也有一些在各个国家的例子，比如在British Telecom公司发生的灾难，但是幸运的是他们把原来的计划废弃了，又重新开始，他们就比Australian Telecom公司幸运，现在我又听说Siemens公司又在造"恐龙"了，他们目前是越来越担心要用来加速执行软件所要使用的昂贵的高速硬件，难道你真的认为那些个多态继承是一种乐趣吗？ <br><br>记者: 噢，但是C++的确是一种可靠的语言啊！ <br><br>Stroustrup: 你是真的相信的，对吧？你有没有真的坐下来用C++开发过项目？我来告诉你会发生什么：首先，我会加入足够的缺陷来让那些微不足道的模块先执行，让工作超载，在工程扫尾的阶段，你回发现几乎所有的模块都会有这种缺陷，这是因为人们以为就是应该这样做，因为在C++的教程中就是这样写的。在相同的模块中执行不同对象的相似操作意味着：有一些东西在各个模块中是完全不相同的。当你有了互不相同的上百个这样的模块，就可以把他们集成在一起了。其次，我再说说所谓的数据隐藏，上帝啊，当我听说了有的小组实现了什么对象协同通信，我真的是憋不住想笑！我看，OO方法中的"协同"这个词可以把项目经理的肋条累断。 <br><br>记者: 我不得不说着太可怕了！你还说这是用来提高程序员的工资，这太龌龊了！ <br><br>Stroustrup: 龌龊？不是这样的，任何人都有选择的权利。我是并不想让事情发展成这个样儿的。不管怎么说，我基本上还是成功的。C++现在已经不行了不是？而且程序员现在还是能挣到高工资的——特别是那些还要维护这些该死的"++"东西的那些程序员。你应该明白如果你去维护一个不是由你开发的C++模块是不可能的。 <br><br>记者: 怎么会这样的？ <br><br>Stroustrup: 你糊涂了？还记得typedef吗？ <br><br>记者: 噢，当然。 <br><br>Stroustrup: 知道要在头文件里发现象'RoofRaised'这样的变量是一个双精度数要用多长的时间吗？想象一下要在一个工程里所有的类定义里寻找那些typedefs <br>... ... <br>... ... <br><br>记者: 那么你为什么认定你已经成功了呢？ <br><br>Stroustrup: 还记得一般一个C程序项目要多长时间吗？一般是6个月。这对于一个要养活妻子孩子的程序员是不够的。如果是一样的项目，但是用C++来开发，会怎么样呢？我告诉你：要一两年才能做完！这不好吗？就是一个小小的编程语言选择的决定，语言程序员就不会轻易的下岗了不是？而且那些个大学已经很久没有传授C了，现在是对C程序员的短缺。特别是对UNIX编程熟悉的程序员。在使用了这么多年的"new"以后，而且一直以来一直都不用担心返回值的问题。还有多少程序员知道使用"malloc"？事实上，大多数的C++程序员舍弃了返回值，无论什么样的结果，甚至于返回了"-1"，其实用不着什么'throw'、'catch'、'try'之类的东西，至少你应该知道产生了错误。 <br><br>记者: 但是继承的确不是可以节省很多时间的吗？ <br><br>Stroustrup: 是吗？你注意过C项目计划和C++的项目计划之间的不同吗？在进行了三次系统功能分解后，要确定所有的东西都可被继承到，如果没有那么说明还是有错，但是有谁在C编程里听说过存储渗漏这个说法？现在你可以在业界的大厂商的产品中发现了！有很多的公司不得不放弃了，并且把工程转包出去，他们知道最后可能象筛沙子似的把内存站用完，他们才不想遭那份罪呢！ <br><br>记者: 也有一些工具来...... <br><br>Stroustrup: 大多数的防渗漏的工具不还是用C++写的。 <br><br>记者: 果把这些东西发表了，我们可能在这个行业里无法立足了，你知道吗？ <br>Stroustrup: 我不相信，就象我所说的，现在C++已经是在垂死挣扎了。任何公司只要清醒，就会认识到用C++来做项目简直是一场灾难。如果还没认识到这些，那就是活该！有一段时间我使劲的劝Dennis Ritchie用C++重写UNIX。 <br><br>记者: 啊？天哪！他是怎么说的？ <br><br>Stroustrup: 我不得不承认他的洞察力，我想他和Brian在很早的时候就清楚的明白了我的意图，但是从来没有说出来，他说如果我愿意的话，他可以帮我用C++写 <br>个DOS。 <br><br>记者: 那么你写了吗？ <br><br>Stroustrup: 事实上，我写了，我完成后可以给你一个DEMO，我在机房里的一台4个CPU的Sparc 20上做的，运行得特别的快，而且只占了70M的硬盘空间。 <br><br>记者: 有For PC的版本吗？ <br><br>Stroustrup: 现在你在开玩笑了，难道你没见过Windows 95吗？我认为它是我成功标志之一， <br><br>记者: 我也总是在想关于Unix++，还是有人在试着搞这么个东西的。 <br><br>Stroustrup: 那是因为他们还没有看到这个采访手迹。 <br><br>记者: 对不起，不过依我看，我们恐怕不会刊发这些东西的。 <br><br>Stroustrup: 但是这是个世纪故事，我只是想让我的程序员伙伴们记住我为他们做了什么，你知道这些个日子里C++程序员可以挣多少钱吗？ <br><br>记者: 我所听说的是一个顶尖的C++程序员一小时可以挣到70～80美圆。 <br>Stroustrup: 知道了吧！而且我打赌他肯定可以挣那么多！！单步跟踪我放在C++里面的那些gotcha，并不是容易的事了。在在项目中使用C++的所有特性即使是有经验的程序员也会感到困惑. 事实上有时侯我也是觉得挺难受的，虽然这个特性是为我的初衷而做的，我几乎喜欢上了这个语言。 <br>记者: 你的意思是说你以前是不喜欢的？ <br><br>Stroustrup: 我是狠它的！难道你不同意它是挺笨重的吗？但是当那本书的版税源源不断的...... 我想你能够明白这些。 <br><br>记者: 等一下，关于参数的定义，请您一定要回答，您是否真的改良了C的指针。 <br>Stroustrup: 呵，我也是总是想知道这个。一开始我认为我做了，但是有一天我和一个刚开始学习 C++的程序员讨论了这个问题。他说："他从来就不知道他的变量是否被引用了，所以我还是在使用指针，那个星号总是在提醒我。" <br>记者: OK，一般在这个时候我一般是说："Thank you very much."，但是现在用在这里好象还是不够。 <br><br>Stroustrup: 答应我一定要发表。 <br><br>记者: 好的，我会通知您的，但是我已经知道了我的编辑会说什么了。 <br><br>Stroustrup: 谁会相信呢？你能把这盘录音带给我拷一个吗？ <br><br>记者: 可以。 <br>正文完
<img src ="http://www.cppblog.com/Randy/aggbug/99939.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Randy/" target="_blank">Randy</a> 2009-11-01 14:08 <a href="http://www.cppblog.com/Randy/archive/2009/11/01/99939.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Google单元测试框架(转)</title><link>http://www.cppblog.com/Randy/archive/2009/06/02/86520.html</link><dc:creator>Randy</dc:creator><author>Randy</author><pubDate>Tue, 02 Jun 2009 03:19:00 GMT</pubDate><guid>http://www.cppblog.com/Randy/archive/2009/06/02/86520.html</guid><wfw:comment>http://www.cppblog.com/Randy/comments/86520.html</wfw:comment><comments>http://www.cppblog.com/Randy/archive/2009/06/02/86520.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Randy/comments/commentRss/86520.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Randy/services/trackbacks/86520.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Google Test是Google C++ Testing Framework的一种非正式的称谓，是google最近发布的一个开源C++测试框架。Google测试框架是在不同平台上（Linux，Mac OS X，Windows，Cygwin，Windows CE和Symbian）为编写C++测试而生成的。它是基于xUnit架构的测试框架，支持自动发现测试，丰富的断言集，用户定义的断言，dea...&nbsp;&nbsp;<a href='http://www.cppblog.com/Randy/archive/2009/06/02/86520.html'>阅读全文</a><img src ="http://www.cppblog.com/Randy/aggbug/86520.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Randy/" target="_blank">Randy</a> 2009-06-02 11:19 <a href="http://www.cppblog.com/Randy/archive/2009/06/02/86520.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++界面库 - Xtreme Toolkit Pro[转载]</title><link>http://www.cppblog.com/Randy/archive/2009/05/18/83310.html</link><dc:creator>Randy</dc:creator><author>Randy</author><pubDate>Mon, 18 May 2009 10:55:00 GMT</pubDate><guid>http://www.cppblog.com/Randy/archive/2009/05/18/83310.html</guid><wfw:comment>http://www.cppblog.com/Randy/comments/83310.html</wfw:comment><comments>http://www.cppblog.com/Randy/archive/2009/05/18/83310.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Randy/comments/commentRss/83310.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Randy/services/trackbacks/83310.html</trackback:ping><description><![CDATA[<p>C++界面库 - Xtreme Toolkit Pro[转载] <br>原文转自：<a href="http://blog.csdn.net/vbvan/archive/2007/11/23/1899282.aspx">http://blog.csdn.net/vbvan/archive/2007/11/23/1899282.aspx</a></p>
<p>一套扩展MFC的界面库，可以很方便的实现各种界面风格。不过话说VC2008的MFC即将集成它竞争对手的产品BCGControl，呵呵</p>
<p>官方网站：<a href="http://www.codejock.com/products/toolkitpro">http://www.codejock.com/products/toolkitpro</a></p>
<p>最新的11.20版本已经支持VC2008了，所以编译没有太大的问题。要注意的一点是，源文件的注释有一些非GBK字符，编译的时候命令行里最好加上/wd4819</p>
<p>使用的时候，只需要在StdAfx.h中加入下面的语句即可</p>
<p>#include &lt;XTToolkitPro.h&gt;</p>
<p>如果你选择static link，那么可以使用宏把不需要的部分排除掉，这样能减少最终生成的EXE的大小</p>
<p>//#define _XTP_EXCLUDE_COMMON<br>#define _XTP_EXCLUDE_TABMANAGER<br>#define _XTP_EXCLUDE_GRAPHICLIBRARY<br>//#define _XTP_EXCLUDE_CONTROLS<br>//#define _XTP_EXCLUDE_COMMANDBARS<br>//#define _XTP_EXCLUDE_DOCKINGPANE<br>//#define _XTP_EXCLUDE_PROPERTYGRID<br>#define _XTP_EXCLUDE_REPORTCONTROL<br>#define _XTP_EXCLUDE_CALENDAR<br>#define _XTP_EXCLUDE_TASKPANEL<br>#define _XTP_EXCLUDE_SHORTCUTBAR<br>#define _XTP_EXCLUDE_SKINFRAMEWORK<br>#define _XTP_EXCLUDE_RIBBON<br>#define _XTP_EXCLUDE_SYNTAXEDIT</p>
<p>另外值得注意的一点是，如果你选择static link，那么需要将XTP的资源导入你的工程之中。比如要使用中文资源，那么把下面的代码加入工程的rc2文件的最后</p>
<p>#define _XTP_RESOURCE_LANGUAGE zh_CN<br>#include &lt;XTToolkitPro.rc&gt;</p>
<p>同时，你还需要修改一下XTP附带的XTToolkitPro.rc中的内容<br>将最后的LANGUAGE_DEFAULT(TaskPanel)改成LANGUAGE_LOCALIZED(TaskPanel)<br>然后在TaskPanel\res目录下将Resource.rc复制成Resource_zh_CN.rc，并将其中的编码改成中文</p>
<p>#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)<br>#ifdef _WIN32<br>LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED<br>#pragma code_page(936)<br>#endif //_WIN32<br>#endif</p>
<p>否则你之后include的资源会变成默认的英文</p>
<p>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>产品介绍：<a href="http://blog.csdn.net/componentcn/archive/2007/04/19/1570086.aspx">http://blog.csdn.net/componentcn/archive/2007/04/19/1570086.aspx</a></p>
<img src ="http://www.cppblog.com/Randy/aggbug/83310.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Randy/" target="_blank">Randy</a> 2009-05-18 18:55 <a href="http://www.cppblog.com/Randy/archive/2009/05/18/83310.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于设计</title><link>http://www.cppblog.com/Randy/archive/2009/05/04/81876.html</link><dc:creator>Randy</dc:creator><author>Randy</author><pubDate>Mon, 04 May 2009 12:38:00 GMT</pubDate><guid>http://www.cppblog.com/Randy/archive/2009/05/04/81876.html</guid><wfw:comment>http://www.cppblog.com/Randy/comments/81876.html</wfw:comment><comments>http://www.cppblog.com/Randy/archive/2009/05/04/81876.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Randy/comments/commentRss/81876.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Randy/services/trackbacks/81876.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
<h2><u><font color=#0000ff>关于设计</font></u></h2>
<div class=postbody><span style="FONT-SIZE: 12px; LINE-HEIGHT: 16px; FONT-FAMILY: Tahoma">
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">设计是一项把需求转换为编码方案的活动。设计在软件开发中是必定存在的，无论何种情况下，我们都需要把需求转化为编码方案。<br style="LINE-HEIGHT: 1.4em">设计是一个不断完善的过程，设计的缺陷可能在设计之初无法被发现，直到设计完成时才被察觉到，这导致了再次设计的需要。注意，我们在首次设计时应该尽可能的避免缺陷的出现，而不是视而不见以求下次解决。<br style="LINE-HEIGHT: 1.4em">设计上的付出是必要的，在设计阶段发现错误并改正比编码后发现相同错误并改正的代价低的多，如果设计的错误拖延到维护阶段，那就更加不堪设想。<br style="LINE-HEIGHT: 1.4em">设计存在优劣，必须明确这一点。敷衍的进行设计后果是很严重的（虽然偶尔也能更加快速的产生产品），糟糕设计的最大特点是无法响应需求变更。但也应该注意，优秀的设计有多种，糟糕的设计也有多种。<br style="LINE-HEIGHT: 1.4em">&nbsp;<br style="LINE-HEIGHT: 1.4em">事物的本质属性是一件事物必须具有的，如果不具有则就不在是该事物。事物的偶然属性是不起解决性作用的属性。例如，车总有轮子，没有了轮子就不在是车，那么轮子就是本质属性，但是轮子可能有 4 个，也可能有 3 个，无论多少个轮子依然是车，那轮子的数目就是偶然属性。<br style="LINE-HEIGHT: 1.4em">本质复杂度源于需求，无论采取何种手段，何种技术都不会对本质复杂度造成任何影响，所以有人才会说，软件开发本身就很复杂（无论使用何种技术开发都是复杂的）。我们需要管理好偶然复杂度（偶然性的复杂度），例如，需求是开发一个可用的计算器程序（图形界面可有可无），这时，开发命令行的计算器就比开发 GUI 的计算器的偶然复杂度小，用 C++ 进行开发其偶然复杂度就比用 Dephi 高。敏捷开发和 Unix 中都强调 KISS，而敏捷开发更加强调应该使用简单的技术和工具，这都是为了避免偶然复杂度过高带来额外的成本开销。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">设计者应该真正理解偶然复杂度，如果设计出来的框架，在进行开发时需要开发人员关注于系统的每个细节，那么对于程序员来说偶然复杂度是高的，相比下，对于每个功能的开发，程序员只需要关心当前编写的任务，那么偶然复杂度是低的（COM 的设计非常强调的一点是封装，而不是复用）。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">&nbsp;</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">设计的基本的原则：</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">1）尽量降低偶然复杂度。如果可以简单的解决问题，那为什么不这么做了？另外某些角度来说：</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">模块化的系统（系统对&#8220;模块&#8221;一词有确切的定义），在一定程度上偶然复杂度较低，模块化的系统让程序员只需要关心当前开发的部分。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">2）尽量保持高内聚，低耦合。高耦合的系统惧怕变动（动一处而牵动全身），变动带来的问题通过关联进行传递。高耦合的系统的关键点在于：系统组成部分的关联过多，导致过多的相互影响，当关联数量到一定程度，整个系统就会很不稳定。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">具体来说：</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">&lt;1&gt; 集成的困难：高耦合的各个程序组成部分需要花费较多时间进行集成。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">&lt;2&gt; 测试的困难：一个部分的问题通过与其他部分关联传递到其他部分，那么意味着一个部分的变动可能导致整个系统的重新测试。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">低耦合：在类这个层次上来说，除了底层的工具类（例如 STL）之外（工具类允许和系统中的大部分类发生关联），应该尽可能的减少类之间的关联。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">3）可扩展。可扩展的一个标志是，无需改变系统底层，即可增加新的功能。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">4）可移植性。可移植性非常特别（似乎违背低偶然复杂度原则），它不同于软件的其他的特性，除非你保证你的项目永远无需移植到其他的环境中去，否则，你应该注意这点，因为通常来说，时间越长，越难移植，甚至最后只能重写，代价非常之高。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">5）分层。分层的系统相对来说偶然复杂度较低，关联较少。每层都有每层的工作，相互影响较小。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">&nbsp;</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">另外，类的粒度也比较重要，大粒度的类间关联少，但是不可避免的就是类自身过于复杂。小粒度的类自身很简单，易于开发和维护，但是类间关联变多，通讯太频繁。粒度过大和过小都会带来较多的问题，应该根据经验作合理设计。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">在 C++ 中使用巨大的类无异于使用 C 语言进行编程，这意味着你抛弃了 C++ 强大的抽象能力。含有巨类的系统中的一个显著的标志是：含有大量重复代码或者相似代码（这归结于 C 语言不够强大的抽象能力和项目在时间上的压力）</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">&nbsp;</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">最后要说的一句是：KISS 和敏捷给太多人以误解，请仔细斟酌它们的含义（有几个人懂得 KISS 的真正含义）。设计是不可避免的，好的设计是至关重要的。好的设计在一定程度上控制了软件的成本，即使你的老板并不明白，但是你应该这么做。</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">&nbsp;</p>
<p style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; LINE-HEIGHT: 1.4em; PADDING-TOP: 0px">author: killercat</p>
</span></div>
<img src ="http://www.cppblog.com/Randy/aggbug/81876.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Randy/" target="_blank">Randy</a> 2009-05-04 20:38 <a href="http://www.cppblog.com/Randy/archive/2009/05/04/81876.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>22条商规 - 艾﹒里斯和杰克﹒特劳特</title><link>http://www.cppblog.com/Randy/archive/2009/05/03/81777.html</link><dc:creator>Randy</dc:creator><author>Randy</author><pubDate>Sun, 03 May 2009 09:57:00 GMT</pubDate><guid>http://www.cppblog.com/Randy/archive/2009/05/03/81777.html</guid><wfw:comment>http://www.cppblog.com/Randy/comments/81777.html</wfw:comment><comments>http://www.cppblog.com/Randy/archive/2009/05/03/81777.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Randy/comments/commentRss/81777.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Randy/services/trackbacks/81777.html</trackback:ping><description><![CDATA[<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>01领先定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>成为第一胜过做得更好</strong></p>
<p style="TEXT-INDENT: 2em">在中国市场上，茅台是第一种高档白酒；中华是第一种高档香烟；健力宝是第一种运动饮料；三枪是第一个内衣品牌；脉动是第一种维生素水；康师傅是第一种高档方便面和瓶装绿茶；金龙鱼是第一个调和油品牌；东方红是第一个拖拉机品牌。今天，除健力宝因企业内部原因导致品牌衰落外，极大多数品牌都仍然占据各自领域的第一位置。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>02品类定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>如果你无法在现有品类中成为第一，那么就创造一个新的品类使自己成为第一。</strong></p>
<p style="TEXT-INDENT: 2em">中国橙汁饮料市场的例子很好的说明了这一定律；汇源成为高浓度果汁的第一品牌之后，鲜橙多开创了低浓度果汁品类，并成为该品类第一；酷儿开创了儿童低浓度果汁品类；美汁源则开创了果肉果汁（果粒橙）品类，成为该品类第一。这些品牌都因开创了一个新品类而获得成功。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>03心智定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>在心智中成为第一胜过在市场中成为第一。</strong></p>
<p style="TEXT-INDENT: 2em">喜之郎并非国内第一个果冻品牌。在喜之郎之前，金娃等品牌已经率先进入市场，但从全国来看，顾客心智中并没有一个公认的果冻品牌，也就是说，首先进入市场的果冻品牌并未进入顾客心智。于是喜之郎依靠突出的形象，并率先在CCTV等大众媒体上进行广告宣传，成功抢先占据心智，从而收获了果冻市场50%以上的份额。</p>
<p style="TEXT-INDENT: 2em">后来，喜之郎公司又故伎重演，推出了美好时光海苔，试图通过大众媒体抢占方便海苔品类，不同的是，方便海苔品类中已经有波力等品牌先入为主，因此美好时光投放了大量广告也没有取得预期效果。</p>
<p style="TEXT-INDENT: 2em">2003年年初，长富出现在央视黄金时段，正式吹响了进军全国的号角。</p>
<p style="TEXT-INDENT: 2em">长富宣称其牛奶&#8220;绿色天然&#8221;，是&#8220;真正顺滑香浓的好奶&#8221;。为了证明其&#8220;高品质奶源&#8221;，长富召开新闻发布会，展示其地处福建武夷山区据称是中国最大最好的奶源基地。后来，长富更是不惜血本，在广东展开&#8220;买24送15&#8221;的促销活动，尽管长富投入了9200万元的广告费，但市场并不为其所动，全国乳业市场的格局并没有因为长富的加入而被打破，甚至连长富最为看重、投入最多的广东市场，也没有实现其市场占有率10%的目标。</p>
<p style="TEXT-INDENT: 2em">拥有一流产品以及广告投入巨大的长富为什么会折戟沉沙呢？</p>
<p style="TEXT-INDENT: 2em">原来，在消费者的心智中，&#8220;最好的奶源来自内蒙古大草原而不是武夷山&#8221;。之一观念早就随着&#8220;天苍苍，野茫茫，风吹草低见牛羊&#8221;的诗句深入人心。加之蒙牛、伊利此前早就在合力宣扬&#8220;内蒙古牛奶好&#8221;。所以，尽管长富说&#8220;如今的内蒙古大草原水土流失严重，日益风蚀沙化，而武夷山处于北纬27度，有中国&#8216;澳洲&#8217;之称&#8221;，但毕竟势单力薄，无法改变消费者心目中&#8220;最好的奶源来自内蒙古&#8221;这一认知。</p>
<p style="TEXT-INDENT: 2em">统一与康师傅在中国大陆市场竞争的实质就是一场先入为主的战争，康师傅进入大陆市场之前在台湾默默无闻，统一则是台湾食品饮料领域的领导者，康师傅率先进入大陆市场推出了中高档方便面，统一随后进入，但康师傅已经先入为主，因此在大陆市场上，实力更强大的统一在方便面领域一直落后于康师傅。之后，康师傅又抢先推出瓶装绿茶、冰红茶等产品，这些产品的市场份额都无一例外的领先于统一。统一唯一的翻身机会在于率先推出了低浓度果汁&#8220;鲜橙多&#8221;，后来，康师傅跟进推出低浓度果汁品牌&#8220;鲜的每日C&#8221;，其销量当然是远远落后于&#8220;鲜橙多&#8221;。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>04认知定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>市场营销不是一场产品之战，而是一场认知之战。</strong></p>
<p style="TEXT-INDENT: 2em">历史总在不断的重演，可口可乐和百事可乐所做的实验，中国的非常可乐也做过，非常可乐也曾经宣称：经过上千次配方改进，测试证明非常可乐更适合中国人的口味。遗憾的是，非常可乐更好的口味无法阻挡可口可乐和百事可乐在中国市场取得成功。</p>
<p style="TEXT-INDENT: 2em">张裕干红葡萄酒在国内大部分地区以&#8220;百年张裕&#8221;的历史资源来向人们推广&#8220;国产高档葡萄酒&#8221;的认知，但在广东地区，张裕品牌却更多地代表低端白兰地。原因在于，张裕低端白兰地在该地区有较长的销售历史、极高的知名度和占有率。这种强烈的认知也影响到张裕的高端干红在该区域难以打开局面。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>05聚焦定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>市场营销最重要的是在潜在顾客心智中占据一个字眼。</strong></p>
<p style="TEXT-INDENT: 2em">在美国市场，佳洁士以聚焦&#8220;防蛀&#8221;概念而成为第一，但在进入中国市场之初，佳洁士因担心&#8220;防蛀&#8221;市场有限，转而宣传口气清新、美白等概念，被一直处于第二的老对手高露洁抓住机会，抢先聚焦于&#8220;防蛀&#8221;概念。等佳洁士重新聚焦于&#8220;防蛀&#8221;之时，高露洁已经先入为主，成为&#8220;防蛀&#8221;牙膏的代名词，并一直领先于对手。</p>
<p style="TEXT-INDENT: 2em">在中国市场的研究表明，大部分购买高露洁的顾客，真正的目的并非为了&#8220;防止蛀牙&#8221;，而是高露洁专注于&#8220;防止蛀牙&#8221;而建立起的专家形象，让顾客认为这个品牌的牙膏更先进、更科学、更能保护牙齿。这就是&#8220;光环效应&#8221;的体现。</p>
<p style="TEXT-INDENT: 2em">曾经被誉为&#8220;中国魔水&#8221;的健力宝，错过了&#8220;聚焦定律&#8221;的机会，它当时有条件聚焦于&#8220;运动饮料&#8221;的概念，舍弃各种汽水、果汁、水、茶等产品，通过极力推广运动饮料而使品类做大做强。随着人们生活水平的提高，对运动的投入程度也越高，运动饮料的前景本来一片光明，可惜健力宝企业却推出了定位不明的新品牌&#8220;第五季&#8221;，还分兵进入酒业，离正道越来越远。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>06专有定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>两个公司不可能在潜在顾客心智中拥有同一个字眼。</strong></p>
<p style="TEXT-INDENT: 2em">金龙鱼因开创了调和油品类而成为国内食用油的领导品牌，因此金龙鱼成了&#8220;调和油&#8221;的代名词。但随着市场的发展，新的单一油种不断兴起，金龙鱼品牌开始推出花生油、葵花籽油、菜籽油、玉米油等多个品类。但在这些品类中，鲁花已经代表花生油、多力已经代表葵花籽油，金龙鱼无法将已经被这些品牌在顾客心智中注册的字眼和概念占为己有，还面临&#8220;调和油&#8221;的认知被稀释，最后沦为混沌品牌的危险。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>07阶梯定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>市场营销战略取决于你在潜在顾客心智阶梯中的层级。</strong></p>
<p style="TEXT-INDENT: 2em">阶梯定律背后蕴涵的营销真谛是：在营销中，心智决定市场；品牌的心智地位决定市场地位；心智份额决定市场份额；蒙牛品牌创立之初，面对强大的伊利，并未采用正面进攻的方式与之竞争，而是打出&#8220;创内蒙乳业第二品牌&#8221;的口号，在顾客心智中与内蒙古第一品牌伊利直接产生关联，达到了迅速有力地提升了蒙牛品牌的心智地位的功效。同时蒙牛很默契地与伊利共同推广&#8220;草原奶&#8221;的概念，推动了自身品牌的高速增长。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>08二元定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>长远来看，任何一个市场都会演化成&#8220;两匹马赛跑&#8221;的局面。</strong></p>
<p style="TEXT-INDENT: 2em">行业巨头的二元化局面在中国企业中已经初步显现：茶饮料领域是康师傅和统一；高档白酒领域是茅台和五粮液；乳业市场是伊利和蒙牛；内衣市场是三枪和宜而爽，&#8230;&#8230;可以预见，随着竞争的加剧，尤其是中国加入WTO以后，竞争壁垒逐渐打破，二元定律在各个领域开始显现出威力，&#8220;两匹马竞争&#8221;的局面将广泛存在于各个行业中。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>09对立定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>若想成为市场第二，那么你的战略应由第一决定。</strong></p>
<p style="TEXT-INDENT: 2em">&#8220;鲜橙多&#8221;在低浓度果汁市场上取得成功之后，汇源、哇哈哈、康师傅纷纷跪进退出相应的模仿产品，但真正成为低浓度果汁领域中第二的品牌并非以上跟进者，而是遵循了对立定律的&#8220;酷儿&#8221;。与&#8220;鲜橙多&#8221;面向大众不同，&#8220;酷儿&#8221;将顾客群定义为&#8220;儿童&#8221;，并在配方中加入&#8220;钙&#8221;，从而成为儿童首选的低浓度果汁。</p>
<p style="TEXT-INDENT: 2em">广州报业市场上，《广州日报》依靠开国内市民报之先河获得迅速发展，成为国内广告收入第一的报纸。面对强大的《广州日报》和老牌的《羊城晚报》，《南方都市报》在面市之初采取了对立面战略，针《广州日报》的大版面、权威、稳重的特点，《南方都市报》采用小版面突出新锐、时尚、从而获得了年轻白领的青睐，一举成为广州第二大报。</p>
<p style="TEXT-INDENT: 2em">最近三年里，QQ成为奇瑞汽车最为畅销的车型，并一举超越奥托成为小型经济型轿车的代表。QQ用时尚、活力、现代的品牌概念一举将奥托定义成老旧、过时、缺乏活力。QQ成功的关键在于成为原先领导者奥托的对立面。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>10分化定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>长期来看，每个品类都将分化成两个或更多品类。</strong></p>
<p style="TEXT-INDENT: 2em">微软在3C计划上浪费了数十亿美金，没有任何结果。在中国，3C融合一直被家电企业当做必然的趋势，TCL就是一个典型。从20世纪90年代中期开始，TCL为3C计划投入了巨资，并为此挖来了有&#8220;打工皇帝&#8221;之称的微软前中国区总裁吴士宏，最终却以信息家电失败、吴黯然辞职而收场。</p>
<p style="TEXT-INDENT: 2em">分化在各个品类中时有发生，以啤酒行业为例，最初是普通啤酒，后来分化出淡啤、清啤、纯生、无醇、黑啤等很多个品类；再如瓶装茶饮料，最初是绿茶，后来分化出冰红茶、冰绿茶、红茶、乌龙茶、茉莉花茶；电视机分化为：CTR、液晶、等离子等品类，甚至空调也分化为中央空调和家用空调，家用空调则进一步分化为卧室空调和客厅空调等种类。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>11长效定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>市场营销的改革需要从长期来看。</strong></p>
<p style="TEXT-INDENT: 2em">诠释长效定律最好的反面例子莫过于春兰空调。1994年春兰空调销售额达53亿，居国内第一，1995年春兰确定了2000年销售额达到180亿的目标，为了达到该目标，春兰进入了彩电、冰箱、洗衣机、摩托车、卡车等领域，销售额实现快速增长。到了2000年，春兰空调销售额达到185亿，但利润开始下滑。到了2005年，春兰多元化的恶果开始显现，持续出现亏损，最终被迫退出股市。</p>
<p style="TEXT-INDENT: 2em">在中国白酒行业里，大量的投入和促销并没有建立起新的强势品牌，而高额的促销、返利、终端费用拖垮了越来越多的企业，行业的领先品牌依旧是几乎从不做促销的茅台、五粮液、剑南春。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>12延伸定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>产品越多，市场越大，阵线越长，赚的钱反而越少。</strong></p>
<p style="TEXT-INDENT: 2em">娃哈哈品牌从AD钙奶延伸到瓶装水、果汁、绿茶、方便面、牛奶、童装等领域，并在短期内实现了销量的增长。哇哈哈的品牌延伸一度被国内部分营销人士称为品牌延伸的的典范，并以此为据反驳定位理论。但实际上，娃哈哈的品牌延伸稀释了人们对该品牌的认知，娃哈哈在延伸领域几乎没有一个处于&#8220;数一数二&#8221;的位置，利润也大幅下滑，这也成为其被迫与达能合资的主要原因。</p>
<p style="TEXT-INDENT: 2em">国内许多企业均成长于需求高涨的特殊时期，凭借制造能力和渠道能力，很容易涉足多产品领域，现在比较成功的企业几乎都是一个品牌横跨多个行业，造成了品牌延伸容易做大做好的错觉。随着各行业竞争增强，企业要普遍承受&#8220;延伸定律&#8221;带来的压力。看看中国最优秀的一些企业，像海尔、康佳、娃哈哈、春兰，都在进行品牌延伸，这种情形着实堪忧。虽然它们目前仍然&#8220;成功&#8221;，但就像一架不符合力学原理的飞机一样，飞得越高越让人担心。</p>
<p style="TEXT-INDENT: 2em">在汽车领域，东风也建造了一顶巨大的帐篷，东风曾经代表卡车，如今东风品牌不仅代表重卡、中卡、轻卡、小卡、面包车、客车，还代表法国轿车（东风标志）、日本轿车（东风日产）、韩国轿车（东风悦达&#183;起亚）、国产MPV（东风风行），这就是东风品牌最致命的营销问题。重卡和轻卡分别被专家品牌占据了两个品类的主导位置，东风处境尴尬。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>13牺牲定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>你如果想取得成功，就必须牺牲一些东西。</strong></p>
<p style="TEXT-INDENT: 2em">中国传统的老八大名酒中，茅台、五粮液、剑南春三个品牌发展成了全国性的领导品牌，并占据了行业的前三名，其余汾酒、古井贡等五个品牌则发展成了区域性品牌，在同一起跑线上的品牌为何有不同的结果呢？进一步对比就可以发现，三个全国性品牌共同的特征是聚焦于一个档次——很短的产品线；五个区域性品牌的共同特点则恰恰相反，全都有多如牛毛的产品，产品覆盖高中低档。以汾酒为例，汾酒的产品多达800多个，其营销负责人还声称&#8220;还远不够，还无法满足需求&#8221;。</p>
<p style="TEXT-INDENT: 2em">红河卷烟厂依靠聚焦于一个品牌——红河，同时红河品牌聚焦于3-10元之间的中低档香烟市场，从而获得了巨大的成功，红河品牌很快成为国内香烟销量最大的三大品牌之一。其后，红河不再满足于低端市场，他先后推出了价格超过70元的红河V8、并在10元以上市场先后推出了红河88、红河V6等产品，这些产品无一例外地以失败而告终，同时也使红河丧失了成为&#8220;中国万宝路&#8221;的绝好机会。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>14特性定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>想要成功，就必须有自己独特的认知或特性，并以此为中心展开营销。</strong></p>
<p style="TEXT-INDENT: 2em">王老吉凉茶以&#8220;预防上火&#8221;的特性获得成功之后，国内饮料企业纷纷推出各种凉茶品牌。虽然表面看来这些品牌都有&#8220;卖点&#8221;，如：&#8220;老翁&#8221;宣传的&#8220;台湾凉茶&#8221;概念；&#8220;邓老&#8221;则先后宣传&#8220;中国凉茶道&#8221;和&#8220;时尚凉茶&#8221;；&#8220;何其正&#8221;宣传&#8220;清火气、养元气&#8221;等，实际上这些品牌都未能聚焦有效特性，更未能从王老吉的对立面发掘出针对性这一特征，从而也未能成为凉茶领域的&#8220;百事可乐&#8221;。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>15坦诚定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>使自己产品深入人心的最有效方法是，首先承认自己的不足，之后再将其转变为优势。</strong></p>
<p style="TEXT-INDENT: 2em">在营销中使用&#8220;坦诚&#8221;定律需要极大的勇气，中国企业在此方面的实践案例较少。当企业面临危机的时候，坦诚往往是必须的。三聚氰胺的危机使三鹿这个国内奶粉领域的领导品牌在一夜之间化为乌有，甚至影响到了整个乳品行业，如果在危机到来的第一时间三鹿想到了坦诚定律并付诸行动，及时向大众承认问题，并召回产品，承担责任的话，三鹿本可以避免这场灭顶之灾。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>16唯一定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>大多数情况下，你的竞争对手只有一个容易攻破的薄弱环节，正是这个环节，应该成为你全力攻击的焦点。</strong></p>
<p style="TEXT-INDENT: 2em">可口可乐在中国瓶装茶市场上进行过六次尝试，先后推出过&#8220;天与地&#8221;茶饮料、蓝枫日式蜂蜜绿茶、阳光冰爽果茶、雀巢&#8220;西式冰爽茶&#8221;、茶研工坊&#8220;草本茶饮料&#8221;，都以失败而告终，最近推出的&#8220;原叶&#8221;系列虽耗资巨大，但也前景黯淡。可口可乐要在茶饮料上有所作为，就必须找到竞争对手最易攻破的薄弱环节，否则一切都将徒劳无功。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>17莫测定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>除非是你为竞争对手制定计划，否则你无法预测未来</strong></p>
<p style="TEXT-INDENT: 2em">在竞争最为激烈的家电行业，对未来的预测和判断直接影响到中国品牌的整体表现。90年代，中国企业逐步掌握CRT彩电的核心技术，在中国CRT电视机市场中，中国彩电企业更曾占据98%以上的份额，索尼、东芝等品牌的CRT产品一度撤出中国。但中国彩电企业都未能预料到CRT将迅速衰退，液晶显示很快成为市场主流。2005年开始，索尼、夏普、LG\三星等日韩彩电企业凭借液晶平板产品卷土重来，迅速占领了中国内地一二线城市市场，中国家电品牌鲜有液晶面板生产能力，被迫集体退守三四级市场。</p>
<p style="TEXT-INDENT: 2em">即使在新技术的发展方向，彩电企业一度普遍认为等离子大屏幕彩电将成为市场主流，于是松下、富士通、NEC以及中国的长虹等大批企业则押宝等离子技术，夏普、三星等企业则大力投入研发液晶平板计数。如今，市场证明最初不被看好的液晶显示屏成为了主流。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>18成功定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>成功经常导致自大，而自大导致失败。</strong></p>
<p style="TEXT-INDENT: 2em">企业因专注、聚焦而成功，一旦成功就感觉无所不能，摈弃最初的成功经验。从某种程度上讲，大部分国内知名企业都经历了盲目扩张、多元发展然后陷入困境这一几乎必然的过程。从联想、海尔、TCL、长虹、奇瑞等各个企业身上都可以看到&#8220;成功定律&#8221;的影子。打破&#8220;成功定律&#8221;的宿命或许是中国企业面临的最大挑战。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>19失败定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>面对失败，更佳的战略是尽早发现错误并及时采取措施以停止损失。</strong></p>
<p style="TEXT-INDENT: 2em">如果失败无可避免，那么及时撤退可以起到亡羊补牢的效果。联想出售手机业务、创维以2元的低价出售手机业务都属于此类举措。所以，无论是联想还是创维，消息宣布之后，股市都以大幅反弹作为回应，证明及时放弃属于重大利好已是共识。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>20炒作定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>实际情况往往与媒体宣传的相反</strong></p>
<p style="TEXT-INDENT: 2em">CCTV黄金时间广告招标的首届标王秦池可谓阐释&#8220;炒作定律&#8221;的最佳案例，借助大规模的广告投放以及&#8220;标王&#8221;效应带来的大量媒体报道，在较短时间内，秦池的知名度和关注度空前提升，这同时也为后来负面新闻的产生及迅速扩散累积了巨大的势能，最终导致了无可挽回的结果。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>21趋势定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>通过淡化时尚，就能使产品流行的时间延长，从而使它更像是一种趋势。</strong></p>
<p style="TEXT-INDENT: 2em">与趋势定律相悖，很多企业追逐的恰恰是成为时尚与潮流。健力宝推出的&#8220;第五季&#8221;饮料正是希望通过时尚和潮流来推动品牌的成长，该品牌涵盖了可乐、茶饮料、纯净水、果汁等品类，口号为&#8220;现在流行第五季&#8221;。在一阵风潮之后，第五季几乎一无所剩。</p>
<p style="TEXT-INDENT: 2em" align=center><font color=#0000ff>22资源定律</font></p>
<p style="TEXT-INDENT: 2em" align=center><strong>就算是世界上最好的想法，如果没有启动资金，它也不会成为现实。</strong></p>
<p style="TEXT-INDENT: 2em">如何使市场第一成为心智第一，充分的资源是必须的，国内企业界流传的&#8220;万燕悖论&#8221;：先驱者往往成为先烈；从某种意义上正是说明了资源的重要性。万燕发明了VCD，但是爱多和步步高却通过大规模的广告传播率先抢先占据了顾客心智，最终，万燕只能以失败收场。因此，对于创业家而言，找到好的战略与找到足够的钱同样重要。</p>
<p style="TEXT-INDENT: 2em">营销领域的黄埔军校，国内洗化领域的领导者宝洁公司深谙资源法则的重要性，保洁一直是国内最大的广告主，每年有多达16个亿以上的广告预算，每一个新产品的推出都有庞大的预算提供有力的支持。</p>
<img src ="http://www.cppblog.com/Randy/aggbug/81777.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Randy/" target="_blank">Randy</a> 2009-05-03 17:57 <a href="http://www.cppblog.com/Randy/archive/2009/05/03/81777.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ 枚举类型的思考</title><link>http://www.cppblog.com/Randy/archive/2009/03/23/77612.html</link><dc:creator>Randy</dc:creator><author>Randy</author><pubDate>Mon, 23 Mar 2009 10:16:00 GMT</pubDate><guid>http://www.cppblog.com/Randy/archive/2009/03/23/77612.html</guid><wfw:comment>http://www.cppblog.com/Randy/comments/77612.html</wfw:comment><comments>http://www.cppblog.com/Randy/archive/2009/03/23/77612.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/Randy/comments/commentRss/77612.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Randy/services/trackbacks/77612.html</trackback:ping><description><![CDATA[<p>至从C语言开始enum类型就被作为用户自定义分类有限集合常量的方法被引入到了语言当中，而且一度成为C++中定义编译期常量的唯一方法（后来在类中引入了静态整型常量）。<br>根据上面对enum类型的描述，有以下几个问题：<br>1.到底enum所定义出来的类型是一个什么样的类型呢？<br>2.作为一个用户自定义的类型其所占用的内存空间是多少呢？<br>3.使用enum类型是否真的能够起到有限集合常量的边界约束呢？<br>4.大家可能都知道enum类型和int类型具有隐示（自动）转换的规则，那么是否真的在任何地方都可以使用enum类型的变量来代替int类型的变量呢？</p>
<p>&nbsp;1. 到底enum所定义出来的类型是一个什么样的类型呢？<br>&nbsp;在C++中大家都知道仅仅有两种大的类型分类：POD类型（注（1））和类类型。<br>&nbsp;enum所定义的类型其实属于POD类型，也就是说它会参与到POD类型的隐示转换规则当中去，所以才会出现enum类型与int类型之间的隐示转换现象。<br>&nbsp;那么也就是说enum所定义的类型不具备名字空间限定能力（因为不属于类类型），其所定义的常量子具备和enum类型所在名字空间相同的可见性，由于自身没有名字限定能力，所以会出现名字冲突现象。<br>&nbsp;如：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct CEType<br>&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; enum EType1 { e1, e2 };<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enum EType2 { e1, e2 };<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 上面的例子会出现e1、e2名字冲突编译时错误，原因就在于枚举子（e1、e2）是CEType名字空间中的名字，同样在引用该CEType中的枚举子时必须采用CEType::e1这样的方式进行，而不是CEType::EType1::e1来进行引用。</p>
<p>&nbsp;&nbsp;&nbsp; 注（1）POD类型：<br>&nbsp;你可以将 POD 类型看作是一种来自外太空的用绿色保护层包装的数据类型，POD 意为&#8220;Plain Old Data&#8221;（译者：如果一定要译成中文，那就叫&#8220;彻头彻尾的老数据&#8221;怎么样！）这就是 POD 类型的含义。<br>&nbsp;其确切定义相当粗糙（参见 C++ ISO 标准），其基本意思是 POD 类型包含与 C 兼容的原始数据。<br>&nbsp;例如，结构和整型是 POD 类型，但带有构造函数或虚拟函数的类则不是。 <br>&nbsp;POD 类型没有虚拟函数，基类，用户定义的构造函数，拷贝构造，赋值操作符或析构函数。<br>　　&nbsp;为了将 POD 类型概念化，你可以通过拷贝其比特来拷贝它们。此外， POD 类型可以是非初始化的。</p>
<p>&nbsp;2. 作为一个用户自定义的类型其所占用的内存空间是多少呢？<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;该问题就是sizeof( EType1 )等于多少的问题，是不是每一个用户自定义的枚举类型都具有相同的尺寸呢？<br>&nbsp;在大多数的32位编译器下（如：VC++、gcc等）一个枚举类型的尺寸其实就是一个sizeof( int )的大小，难道枚举类型的尺寸真的就应该是int类型的尺寸吗？<br>&nbsp;其实不是这样的，在C++标准文档（ISO14882）中并没有这样来定义， <br>&nbsp;标准中是这样说明的：&#8220;枚举类型的尺寸是以能够容纳最大枚举子的值的整数的尺寸&#8221;，<br>&nbsp;同时标准中也说名了：&#8220;枚举类型中的枚举子的值必须要能够用一个int类型表述&#8221;， <br>&nbsp;也就是说，枚举类型的尺寸不能够超过int类型的尺寸，但是是不是必须和int类型具有相同的尺寸呢？<br>&nbsp;上面的标准已经说得很清楚了，只要能够容纳最大的枚举子的值的整数就可以了，那么就是说可以是char、short和int。<br>&nbsp;例如：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enum EType1 { e1 = CHAR_MAX };<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enum EType2 { e2 = SHRT_MAX };<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enum EType3 { e3 = INT_MAX&nbsp; };<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 上面的三个枚举类型分别可以用char、short、int的内存空间进行表示，也就是：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sizeof( EType1 ) == sizeof( char&nbsp; );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sizeof( EType2 ) == sizeof( short );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sizeof( EType3 ) == sizeof( int&nbsp;&nbsp; );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 那为什么在32位的编译器下都会将上面三个枚举类型的尺寸编译成int类型的尺寸呢？<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 主要是从32位数据内存对其方面的要求进行考虑的，在某些计算机硬件环境下具有对齐的强制性要求（如：sun SPARC），<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 有些则是因为采用一个完整的32位字长CPU处理效率非常高的原因（如：IA32）。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 所以不可以简单的假设枚举类型的尺寸就是int类型的尺寸，说不定会遇到一个编译器为了节约内存而采用上面的处理策略。<br>&nbsp;&nbsp;&nbsp; 3. 使用enum类型是否真的能够起到有限集合常量的边界约束呢？<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 首先看一下下面这个例子：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enum EType { e1 = 0, e2 };<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void func1( EType e )<br>&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; if ( e == e1 )<br>&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; // do something<br>&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; // do something because e != e1 must e == e2<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void func2( EType e )<br>&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; if ( e == e1 )<br>&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; // do something<br>&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; else if ( e == e2 )<br>&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; // do something<br>&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; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; func1( static_cast&lt;EType&gt;( 2&nbsp; ) );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; func2( static_cast&lt;EType&gt;( -1 ) );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 上面的代码应该很清楚的说明了这样一种异常的情况了，在使用一个操出范围的整型值调用func1函数时会导致函数采取不该采取的行为，而第二个函数可能会好一些他仅仅是忽略了超出范围的值。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这就说明枚举所定义的类型并不是一个真正强类型的有限常量集合，这样一种条件下和将上述的两个函数参数声明成为整数类型没有任何差异。所以以后要注意标准定义中枚举类型的陷阱。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （其实只有类类型才是真正的强类型）<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; 4. 是否真的在任何地方都可以使用enum类型的变量来代替int类型的变量呢？<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通过上面的讨论，其实枚举类型的变量和整型变量具有了太多的一致性和可互换性,那么是不是在每一个可以使用int类型的地方都可以很好的用枚举类型来替代呢？<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 其实也不是这样的，毕竟枚举类型是一个在编译时可区分的类型，<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 同时第2点的分析枚举类型不一定和int类型具有相同的尺寸，这两个差异就决定了在某些场合是不可以使用枚举类型来代替int类型的。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如：<br>&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; enum EType { e1 = 0, e2, e3 };<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EType val;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; std::cin &gt;&gt; val;<br>&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; enum EType { e1 = 0, e2, e3 };<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EType val;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; std::scanf( "%d", &amp;val );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 上面的两种情况看是基本上属于同一种类型的问题，其实不然。第一种情况会导致编译时错误，<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 会因为std::cin没有定义对应的枚举类型的重载&gt;&gt;运算符而出错，这就说明枚举类型是一种独立和鉴别的类型；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 而第二种情况不会有任何编译时问题，但是可能会导致scanf函数栈被破坏而使得程序运行非法，为什么会这样呢？<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 上面已经分析过了枚举类型变量的尺寸不一定和int类型相同，这样一来我们采用%d就是说将枚举类型变量val当作4字节的int变量来看待并进行参数压栈，<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 而在某些编译器下sizeof( val )等于1字节，这样scanf函数就会将val变量地址中的后续的三字节地址也压入栈中，<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 并对其进行赋值，也许val变量后续的三个字节的地址没有特殊含义可以被改写（比如是字节对齐的空地址空间），<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 可能会认为他不会出现错误，其实不然，在scanf函数调用结束后会进行栈清理，<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这样一来会导致scanf函数清理了过多的地址空间，从而破坏了外围函数的栈指针的指向，从而必然会导致程序运行时错误。</p>
<p>由上面的说明枚举类型有那么多的缺点，那我们怎样才能够有一个类型安全的枚举类型呢？实际上，在最新的 C++0x 标准草案中有关于枚举作用域问题的提案，但最终的解决方案会是怎样的就无法未卜先知了，毕竟对于象 C++ 这样使用广泛的语言来说，任何特性的增删和修改都必须十分小心谨慎。</p>
<p>当然，我们可以使用一些迂回的方法来解决这个问题（C++ 总是能给我们很多惊喜和意外）。</p>
<p>例如，我们可以把枚举值放在一个结构里，并使用运算符重载来逼近枚举的特性：</p>
<p>struct FileAccess {<br>&nbsp;&nbsp;&nbsp; enum __Enum {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Read = 0x1,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Write = 0x2<br>&nbsp;&nbsp;&nbsp; };<br>&nbsp;&nbsp;&nbsp; __Enum _value; // 枚举值</p>
<p>&nbsp;&nbsp;&nbsp; FileAccess(int value = 0) : _value((__Enum)value) {}<br>&nbsp;&nbsp;&nbsp; FileAccess&amp; operator=(int value) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this-&gt;_value = (__Enum)value;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return *this;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; operator int() const {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this-&gt;_value;<br>&nbsp;&nbsp;&nbsp; }<br>};</p>
<p>我们现在可以按照希望的方式使用这个枚举类型：</p>
<p>FileAccess access = FileAccess::Read;</p>
<p>并且，因为我们提供了到 int 类型的转换运算符，因此在需要 int 的地方都可以使用它，例如 switch 语句：</p>
<p>switch (access) {<br>&nbsp;&nbsp;&nbsp; case FileAccess::Read:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>&nbsp;&nbsp;&nbsp; case FileAccess::Write:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>}</p>
<p>当然我们不愿意每次都手工编写这样的结构。通过使用宏，我们可以很容易做到这一点：</p>
<p>#define DECLARE_ENUM(E) \<br>struct E \<br>{ \<br>public: \<br>&nbsp;&nbsp;&nbsp; E(int value = 0) : _value((__Enum)value) { \<br>&nbsp;&nbsp;&nbsp; } \<br>&nbsp;&nbsp;&nbsp; E&amp; operator=(int value) { \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this-&gt;_value = (__Enum)value; \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return *this; \<br>&nbsp;&nbsp;&nbsp; } \<br>&nbsp;&nbsp;&nbsp; operator int() const { \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this-&gt;_value; \<br>&nbsp;&nbsp;&nbsp; } \<br>\<br>&nbsp;&nbsp;&nbsp; enum __Enum {</p>
<p>#define END_ENUM() \<br>&nbsp;&nbsp;&nbsp; }; \<br>\<br>private: \<br>&nbsp;&nbsp;&nbsp; __Enum _value; \<br>};</p>
<p>我们现在可以按如下的方式定义前面的枚举，并且不比直接写 enum 复杂多少。</p>
<p>DECLARE_ENUM(FileAccess)<br>&nbsp;&nbsp;&nbsp; Read = 0x1,<br>&nbsp;&nbsp;&nbsp; Write = 0x2,<br>END_ENUM()</p>
<p>DECLARE_ENUM(FileShare)<br>&nbsp;&nbsp;&nbsp; Read = 0x1,<br>&nbsp;&nbsp;&nbsp; Write = 0x2,<br>END_ENUM()</p>
<img src ="http://www.cppblog.com/Randy/aggbug/77612.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Randy/" target="_blank">Randy</a> 2009-03-23 18:16 <a href="http://www.cppblog.com/Randy/archive/2009/03/23/77612.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于团队决策</title><link>http://www.cppblog.com/Randy/archive/2009/03/11/76201.html</link><dc:creator>Randy</dc:creator><author>Randy</author><pubDate>Wed, 11 Mar 2009 04:07:00 GMT</pubDate><guid>http://www.cppblog.com/Randy/archive/2009/03/11/76201.html</guid><wfw:comment>http://www.cppblog.com/Randy/comments/76201.html</wfw:comment><comments>http://www.cppblog.com/Randy/archive/2009/03/11/76201.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Randy/comments/commentRss/76201.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Randy/services/trackbacks/76201.html</trackback:ping><description><![CDATA[<p><a href="http://creativecommons.org/licenses/by/3.0/deed.zh" target=_blank><font color=#c0272a>版权声明</font></a>：转载时请以超链接形式标明文章原始出处和作者信息及<a href="http://bangzhuzhongxin.blogbus.com/logs/11205960.html" target=_blank><font color=#c0272a>本声明</font></a><br><a href="http://spelldev.blogbus.com/logs/11066253.html"><font color=#c0272a>http://spelldev.blogbus.com/logs/11066253.html</font></a><br><br></p>
<p align=center><strong><span>关于团队决策</span></strong></p>
<p align=center><strong></strong></p>
<span><font color=#c0c0c0 size=2>转载请注明作者和出处，如有商业用途请联系作者kingcrimson at tom.com</font><strong>&nbsp;</strong></span>
<p><span>目前的企业中，团队决策已经成为一个必不可少的环节。团队决策具有以下几个好处：</span><span><font face="Times New Roman">(1)</font></span><span>信息量不断扩大，知识随之增长；</span></p>
<p><span><font face="Times New Roman">(2)</font></span><span>多种不同的观点在一起擦出更多火花；</span></p>
<p><span><font face="Times New Roman">(3)</font></span><span>团队成员执行时更愿意接收；</span></p>
<p><span><font face="Times New Roman">(4)</font></span><span>众人决策比个人决策更具有准确性、权威性、合理性；</span></p>
<p><span><font face="Times New Roman">(5)</font></span><span>大家共同达成结论，分享和扩散责任。</span></p>
<p><span>迅速而有效的做出决策，是现代化企业的一个必备的要求。如何做出合理而有效的决策，如何统一团队意见，减少分歧，是团队决策中要面临的首要问题。</span></p>
<p><span><span><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span><span>在日常工作中，我们经常会遇到以下情景的问题：会议拖沓冗长，问题悬而未决，与会人员各抒己见，大家没精打采，甚至发生口舌之争&#8230;&#8230;像这样的问题，对于企业的工作进度是十分有害的。在通常的工作进度中，有数量众多的问题需要团队成员达成一个解决办法。如果不能进行有效的团队决策，将会对整个项目造成严重影响。</span></p>
<p><span><span><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span><span>例如，长时间未解决问题，会使团队成员的心理产生焦虑情绪，破坏他们的积极性。团队成员会对工作环境及决策人产生质疑。时间久了，团队的凝聚力会下降，同时工作质量也会急速下降。另一方面，迅速的解决问题，却没有有效的解决问题，也是对团队工作的一个危害。比如，团队的意见没有达成一致，但决议已经确定。一些团队成员找不到合理的理由来相信这种决策，他们就会在工作中不能有效的贯彻这个决议。团队工作是一项发挥每个人的作用的工作方式，只要一个环节出了差错，就可能会导致全盘皆负。同时，这种工作状态也会影响到团队配合和整体士气。</span></p>
<p><span><span><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span><span>因此，对团队决策的要求最重要就在于&#8220;效率&#8221;。不仅要做出合理而有效的决策，还要迅速、敏捷，减少工作进度的延误。</span></p>
<span><font face="Times New Roman">&nbsp;</font></span>
<p><span><span><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span><span>为了达成此目标，可以参照以下的解决方案。</span></p>
<p><span><span><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span><span>首先，在进行团队决策之前，必须存在一个主持人，或者协调者。他最好不是决策者，并且不带有主观意向。主持人的工作将是团队决策的关键部分，贯穿于整个流程。团队决策的工作模式，和其它工作一样，都是按照提出问题、分析问题、解决问题的流程进行的。以下便是团队决策的简单流程：</span></p>
<span><font face="Times New Roman">&nbsp;</font></span><strong><span>明确问题，对问题进行评估。</span></strong>
<p><span>作为发起团队决策的主持人，在初期准备阶段，必须先明确问题，对问题进行评估。主持人应该制定出问题的重要等级，以便于采取何种方式来进行团对决策。如果是一个复杂的问题，需要将问题转化为若干的小问题，以减少决策中的复杂度。在这个阶段，还要收集与问题有关的相关资料，这样可以使决策过程更有据可循，加快决策流程。总之，准备工作做的越充分，对于之后的决策流程是越有利的。</span></p>
<span><font face="Times New Roman">&nbsp;</font></span><strong><span>制定合理的决策人选。</span></strong>
<p><span>这个步骤也是非常重要的。对于主持人来说，他可能不具备制定人选的权力。（这部分一般是显而易见的或者由团队领导来决定）但是主持人可以对决策人选进行编排和搭配。一般对于小规模的团队，问题可能不是很大。但是大规模的团队，如果不进行合理的编排，将会使决策过程的变得混乱而拖沓。这里，可以采取几个有效的方式来编排决策人员。比如，按职能划分，按个人对于问题的重要程度划分等。常见的做法是，把一个大的团队划分成若干小组，每个小组尽可能达成一致意见，最后再统一达成决策。</span></p>
<span><font face="Times New Roman">&nbsp;</font></span><strong><span>选择合适的决策方式。</span></strong>
<p><span>一般的决策方式就是会议。不管是何种类型的会议，都是决策过程中必不可少的过程。作为主持人，需要制定用何种方式来进行会议。以下有一些可以参考的方式：</span></p>
<p><span><span><font face="Times New Roman">1.<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></font></span></span><span>头脑风暴法</span></p>
<p><span>头脑风暴法的一般步骤：</span></p>
<p><span><font face="Times New Roman">(1)</font></span><span>所有的人无拘无束提意见，越多越好，越多越受欢迎。</span></p>
<p><span><font face="Times New Roman">(2)</font></span><span>通过头脑风暴产生点子，把它公布出来，供大家参考，让大家受启发。</span></p>
<p><span><font face="Times New Roman">(3)</font></span><span>鼓励结合他人的想法提出新的构想。</span></p>
<p><span><font face="Times New Roman">(4)</font></span><span>与会者不分职位高低，都是团队成员，平等议事。</span></p>
<p><span><font face="Times New Roman">(5)</font></span><span>不允许在点子汇集阶段评价某个点子的好坏，也不许反驳别人的意见。</span></p>
<p><span>研究表明，大家在无拘无束、相互激荡的情形下汇集的点子往往比一般方法所汇集的点子多</span><span><font face="Times New Roman">70%</font></span><span>。</span></p>
<p><span><span><font face="Times New Roman">2.<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></font></span></span><span>德尔菲法</span></p>
<p><span>德尔菲法又叫专家群体决策法，就是由一群专家来达成团队的决策。</span></p>
<p><span><font face="Times New Roman">(1)</font></span><span>德尔菲法的特点</span></p>
<p><span>让专家以匿名群众的身份参与问题的解决，有专门的工作小组通过信函的方式进行交流，避免大家面对面讨论带来消极的影响。</span></p>
<p><span><font face="Times New Roman">(2)</font></span><span>德尔菲法的一般步骤</span></p>
<p><span>①</span><span>由工作小组确定问题的内容，并设计一系列征询解决问题的调查表；</span></p>
<p><span>②</span><span>将调查表寄给专家，请他们提供解决问题的意见和思路，专家间不沟通，相互保密；</span></p>
<p><span>③</span><span>专家开始填写自己的意见和想法，并把它寄回给工作小组；</span></p>
<p><span>④</span><span>处理这一轮征询的意见，找出共同点和各种意见的统计分析情况；将统计结果再次返还专家，专家结合他人意见和想法，修改自己的意见并说明原因；</span></p>
<p><span>⑤</span><span>将修改过的意见进行综合处理再寄给专家，这样反复几次，直到获得满意答案。</span></p>
<p><span>德尔菲法用于<span>团队决策</span>可以进行一些变通：比方说将专家换成团队成员、加入外部专家、为了减少成本，提高效率可以不采取信函方式，而直接沟通。</span></p>
<p><span><span><font face="Times New Roman">3.<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></font></span></span><span>异地思考法</span></p>
<p><span>异地思考法就是让团队离开原来的工作环境，摆脱日常事物的干扰，到另外的地方进行专门研究。比方说企业领导把管理人员和专业技术人员请到乡村别墅，住上两天，专门研究企业发展中出现的重大问题。让参与决策的人离开办公室，到一个新的环境讨论问题，使他们摆脱工作环境中上下级界限的问题，隔离繁琐事情的干扰。由于大家畅所欲言、思想活跃，就可以提出一种高水平的构想，最后做出高水平的决策。</span></p>
<span><font face="Times New Roman">&nbsp;</font></span>
<p><span>这些方式只是简单的模板或示例。不管采用哪一种方法。对于主持人来说，必须做到：组织良好的决策流程，控制决策流程的实施，协调决策过程中的气氛。</span></p>
<span><font face="Times New Roman">&nbsp;</font></span><strong><span>整理决议，结束决策过程。</span></strong>
<p><span>这个步骤是一个关键，标志着决策的成形。在团队决策中，一般会存在一个最终决策人的角色。他可能是团队的领导，或者是这个问题的最大成分负责人。而主持人的工作，就要协调好最终决策人和团队成员的关系，并辅佐最终决策人做出决策。最终决策人对于问题有自己的意见，同时他也可能是问题解决方案的最终制定者。为了避免最终决策人对团队决策造成不利的影响，比如团队成员因为某些原因不愿或不敢发表自己的意见，主持人需要控制好最终决策人的参与方式。这需要注意几个问题：</span></p>
<p><span><span><font face="Times New Roman">1.<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></font></span></span><span>不要让最终决策人过早的参与到团队决策中。这并不时是说在时间方面，而是不要让最终决策人的意见干涉到团队成员制定决策的过程。如果最终决策人过早的给出了自己的意见，其它团队成员可能会被限制住思考的界限，或者失去决策的动力。</span></p>
<p><span><span><font face="Times New Roman">2.<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></font></span></span><span>不要让最终决策人与问题分离太远。作为最终决策人，必须付出比团队成员更多的精力去了解问题和分析问题，才能保证决策的正确实施。如果对问题了解不充分，会使团队成员对最终决策产生怀疑和抵触。</span></p>
<p><span><span><font face="Times New Roman">3.<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></font></span></span><span>明确责任承担方式。这是团队决策中一个敏感部分。主持人和最终决策人必须制定出合理的责任承担方式，并告知团队成员。这个过程可能比较艰难，但一定要评估出决策带来的风险，并制定出后续的解决方案，尽量使风险带来的损失减少到最小。</span></p>
<span><font face="Times New Roman">&nbsp;</font></span>
<p><span>以上便是团队决策一个简单流程。真正的实施，还要根据具体情况做出合理的应用和变化。团队决策中，会面临着很多问题，使团队决策变得艰难而缓慢。其中最容易出现的两个误区，就是<strong>团队偏极（</strong></span><strong><span><font face="Times New Roman">group polarization</font></span></strong><strong><span>）</span></strong><span>和<strong>集一思考（</strong></span><strong><span><font face="Times New Roman">groupthink</font></span></strong><strong><span>）</span></strong><span>。</span></p>
<p><span>团队偏极是指团队的综合决策偏向极端化。</span><span><font face="Times New Roman">1961</font></span><span>年，美国麻省理工大学做过一项研究，分两阶段进行：第一阶段是问卷方式调查工业届从业人员对某些后果不确定问题的态度。第二阶段是邀请受调查者出席一场座谈会，要他们面对调查问卷上同样的问题，并做出决策。最后比较两阶段的决策时发现团体决策远较个人决策为极端，个人决策比较谨慎，团体决策比较冒险。后来又经过心理学家反复研究发现团体决策具有极端化倾向，但是极端化的方向不仅限于冒险激进的一端，而是也可能出现在谨慎保守的另一端。如果团体成员多数是属于冒险激进分子，那么他们所做出的决策就会更为冒险激进，如果团体成员多数属于谨慎保守者，那么他们所做出的决策就会更为谨慎保守。团体偏极的现象在社会生活中是很常见的。社会上有不同团体社团，有的保守，有的激进，经常可见的现象是你与保守派中的个人接触，他未必保守，你与激进派中个人接触，他未必激进，可是一经团体决策，就马上体现出很强的保守或激进性了。所以现在很多人回想起当年文化大革命中做红卫兵的一些经历，怎么都不会相信，以自己的个性当年会做出那么离谱的事情，这大体也是因为团体决策的关系。</span></p>
<p><span>对于团队偏极的另一个解释是是：参与决策者由于生怕被别人认为自己是极端主义者，个人在决策时往往会回避一些自己认为是比较理想（极端）的立场。然而在小组讨论各成员将自己个人看法与其他人的立场比较时，会发现别人的意见更加接近于自己心目中的理想，也就是说可能听到别人所持的理由更优于自己。这种发现加重了他自己态度上原本极端的程度，促使他（她）改变原先决定而选择相比之下更加理想（极端）的决定，从而整体上使意见更加偏向极端。</span></p>
<p><span>相对于团队偏极，集一思考的害处更大。所谓的集一思考是指某项团队决策是在全体成员毫无异议的情况下达成的。本来任何问题的取决或多或少都会有所争议，就事而言有利有弊，就人而言，见仁见智。总不至于团体讨论时全数通过毫无疑义。但是集一思考这种现象是确实存在的，专政社会里集一思考不足为奇怪，这里就不列举了，但是像美国这样的民主社会，也还是屡见不鲜，甚至往往还是牵涉到国家兴亡的大事。比如</span><span><font face="Times New Roman">1942</font></span><span>年罗斯福总统任内的日军偷袭珍珠港事件，</span><span><font face="Times New Roman">1961</font></span><span>年肯尼迪总统任内秘密订立的突袭古巴猪猡湾方案，甚至</span><span><font face="Times New Roman">1972</font></span><span>年尼克松总统任内的水门事件无一不是有智囊团所作的团队决策所致。</span></p>
<p><span>由于要取得意见一致的压力太大从而压制了决策成员对行动计划的客观评估的思维方式。由于要努力地维护团队的凝聚力和取得意见一致，成员们不自觉地放弃了挑剔的想法和对行动计划的优缺点进行检讨。然而所放弃的恰恰是科学决策的必须过程。因此&#8220;集一思考&#8221;的典型结果就是考虑不周的决定。</span></p>
<p><span>在四种处境下&#8220;集一思考&#8221;发生的可能性比较大：危机处境，高度团结的团队，缺乏局外人的判断和检视，以及过于强调自己意见的团队领导。</span></p>
<p><span>要避以上两个误区，需要团队决策主持人严谨的贯彻团队决策流程，并制定出面对问题的不同解决方案。主持人可以在团队决策进行前，进行几次假想的模拟或试验，考虑到不同问题出现的可能性，并制定出相应的解决办法。并且在团队决策进行中，主持人可以根据不同的情形，对决策过程进行相应的调整。</span></p>
<span><font face="Times New Roman">&nbsp;</font></span>
<p><span>综上所述，团队决策是一项技术，也是一门艺术。以上只是关于团队决策的一个笼统的概述和讨论。不管采用何种方式，对团队决策高度重视并有效的控制，将是企业创造高效率工作方式的资本。</span></p>
<span><font face="Times New Roman">&nbsp;</font></span><span><font face="Times New Roman">&nbsp;</font></span><span><font face="Times New Roman">&nbsp;</font></span><span><font face="Times New Roman">&nbsp;</font></span>
<p><span><font face="Times New Roman">King Lee</font></span></p>
<p><span><font face="Times New Roman">2007-1-14</font></span></p>
<img src ="http://www.cppblog.com/Randy/aggbug/76201.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Randy/" target="_blank">Randy</a> 2009-03-11 12:07 <a href="http://www.cppblog.com/Randy/archive/2009/03/11/76201.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Visual Studio 2005常用快捷键</title><link>http://www.cppblog.com/Randy/archive/2008/12/24/70254.html</link><dc:creator>Randy</dc:creator><author>Randy</author><pubDate>Wed, 24 Dec 2008 09:32:00 GMT</pubDate><guid>http://www.cppblog.com/Randy/archive/2008/12/24/70254.html</guid><wfw:comment>http://www.cppblog.com/Randy/comments/70254.html</wfw:comment><comments>http://www.cppblog.com/Randy/archive/2008/12/24/70254.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Randy/comments/commentRss/70254.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Randy/services/trackbacks/70254.html</trackback:ping><description><![CDATA[<strong>调试快捷键<br><br></strong>F6: 生成解决方案<br>Ctrl+F6: 生成当前项目<br>F7: 查看代码<br>Shift+F7: 查看窗体设计器<br>F5: 启动调试<br>Ctrl+F5: 开始执行(不调试)<br>Shift+F5: 停止调试<br>Ctrl+Shift+F5: 重启调试<br>F9: 切换断点<br>Ctrl+F9: 启用/停止断点<br>Ctrl+Shift+F9: 删除全部断点<br>F10: 逐过程<br>Ctrl+F10: 运行到光标处<br>F11: 逐语句<br><br><strong>编辑快捷键</strong><br><br>Shift+Alt+Enter: 切换全屏编辑<br>Ctrl+B,T / Ctrl+K,K: 切换书签开关<br>Ctrl+B,N / Ctrl+K,N: 移动到下一书签<br>Ctrl+B,P: 移动到上一书签<br>Ctrl+B,C: 清除全部标签<br><br>Ctrl+I: 渐进式搜索<br>Ctrl+Shift+I: 反向渐进式搜索<br>Ctrl+F: 查找<br>Ctrl+Shift+F: 在文件中查找<br>F3: 查找下一个<br>Shift+F3: 查找上一个<br>Ctrl+H: 替换<br>Ctrl+Shift+H: 在文件中替换<br>Alt+F12: 查找符号(列出所有查找结果)<br>Ctrl+Shift+V: 剪贴板循环<br><br>Ctrl+左右箭头键: 一次可以移动一个单词<br>Ctrl+上下箭头键: 滚动代码屏幕，但不移动光标位置。<br>Ctrl+Shift+L: 删除当前行<br>Ctrl+M,M: 隐藏或展开当前嵌套的折叠状态<br>Ctrl+M,L: 将所有过程设置为相同的隐藏或展开状态<br>Ctrl+M,P: 停止大纲显示<br>Ctrl+E,S: 查看空白<br>Ctrl+E,W: 自动换行<br>Ctrl+G: 转到指定行<br>Shift+Alt+箭头键: 选择矩形文本<br>Alt+鼠标左按钮: 选择矩形文本<br>Ctrl+Shift+U: 全部变为大写<br>Ctrl+U: 全部变为小写<br><br><strong>代码快捷键</strong><br><br>Ctrl+J / Ctrl+K,L: 列出成员<br>Ctrl+Shift+空格键 / Ctrl+K,P: 参数信息<br>Ctrl+K,I: 快速信息<br>Ctrl+E,C / Ctrl+K,C: 注释选定内容<br>Ctrl+E,U / Ctrl+K,U: 取消选定注释内容<br><br>Ctrl+K,M: 生成方法存根<br>Ctrl+K,X: 插入代码段<br>Ctrl+K,S: 插入外侧代码<br><br>F12: 转到所调用过程或变量的定义<br><strong><br>窗口快捷键</strong><br><br>Ctrl+W,W: 浏览器窗口<br>Ctrl+W,S: 解决方案管理器<br>Ctrl+W,C: 类视图<br>Ctrl+W,E: 错误列表<br>Ctrl+W,O: 输出视图<br>Ctrl+W,P: 属性窗口<br>Ctrl+W,T: 任务列表<br>Ctrl+W,X: 工具箱<br>Ctrl+W,B: 书签窗口<br>Ctrl+W,U: 文档大纲<br><br>Ctrl+D,B: 断点窗口<br>Ctrl+D,I: 即时窗口<br>Ctrl+Tab: 活动窗体切换<br>Ctrl+Shift+N: 新建项目<br>Ctrl+Shift+O: 打开项目<br>Ctrl+Shift+S: 全部保存<br>Shift+Alt+C: 新建类<br>Ctrl+Shift+A: 新建项<br><br><font color=#339966><font color=#ff0000><strong><br></strong></font><br>F5是用调试模式运行,对于程序抛出的异常会进行检查的,有些异常调试器会忽略,有些异常会谈出对话框。哪些异常忽略，哪些谈出对话框是可以设置的。 <br>&nbsp;&nbsp; <br>Ctrl+F5是直接运行程序，调试器完全不管程序运行状态，所以所有未被俘获的异常都回导致程序直接退出。</font>
<img src ="http://www.cppblog.com/Randy/aggbug/70254.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Randy/" target="_blank">Randy</a> 2008-12-24 17:32 <a href="http://www.cppblog.com/Randy/archive/2008/12/24/70254.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>开源日志系统log4cplus</title><link>http://www.cppblog.com/Randy/archive/2008/11/22/67570.html</link><dc:creator>Randy</dc:creator><author>Randy</author><pubDate>Sat, 22 Nov 2008 04:16:00 GMT</pubDate><guid>http://www.cppblog.com/Randy/archive/2008/11/22/67570.html</guid><wfw:comment>http://www.cppblog.com/Randy/comments/67570.html</wfw:comment><comments>http://www.cppblog.com/Randy/archive/2008/11/22/67570.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Randy/comments/commentRss/67570.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Randy/services/trackbacks/67570.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: ### 简介 ###log4cplus是C++编写的开源的日志系统，前身是java编写的log4j系统.受Apache Software License保护。作者是Tad E. Smith。log4cplus具有线程安全、灵活、以及多粒度控制的特点，通过将信息划分优先级使其可以面向程序调试、运行、测试、和维护等全生命周期； 你可以选择将信息输出到屏幕、文件、NT event log、甚至是远程...&nbsp;&nbsp;<a href='http://www.cppblog.com/Randy/archive/2008/11/22/67570.html'>阅读全文</a><img src ="http://www.cppblog.com/Randy/aggbug/67570.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Randy/" target="_blank">Randy</a> 2008-11-22 12:16 <a href="http://www.cppblog.com/Randy/archive/2008/11/22/67570.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>gtest</title><link>http://www.cppblog.com/Randy/archive/2008/11/14/66961.html</link><dc:creator>Randy</dc:creator><author>Randy</author><pubDate>Fri, 14 Nov 2008 14:54:00 GMT</pubDate><guid>http://www.cppblog.com/Randy/archive/2008/11/14/66961.html</guid><wfw:comment>http://www.cppblog.com/Randy/comments/66961.html</wfw:comment><comments>http://www.cppblog.com/Randy/archive/2008/11/14/66961.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Randy/comments/commentRss/66961.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Randy/services/trackbacks/66961.html</trackback:ping><description><![CDATA[<p>断言：<br>ASSERT_TRUE(condition); EXPECT_TRUE(condition); condition为真<br>ASSERT_FALSE(condition);&nbsp;&nbsp;&nbsp; EXPECT_FALSE(condition);&nbsp;&nbsp;&nbsp; condition为假<br><br>ASSERT_EQ(expected, actual);&nbsp;&nbsp;&nbsp; EXPECT_EQ(expected, actual);&nbsp;&nbsp;&nbsp; expected == actual<br>ASSERT_NE(val1, val2);&nbsp; EXPECT_NE(val1, val2);&nbsp; val1 != val2<br>ASSERT_LT(val1, val2);&nbsp; EXPECT_LT(val1, val2);&nbsp; val1 &lt; val2<br>ASSERT_LE(val1, val2);&nbsp; EXPECT_LE(val1, val2);&nbsp; val1 &lt;= val2<br>ASSERT_GT(val1, val2);&nbsp; EXPECT_GT(val1, val2);&nbsp; val1 &gt; val2<br>ASSERT_GE(val1, val2);&nbsp; EXPECT_GE(val1, val2);&nbsp; val1 &gt;= val2<br><br>ASSERT_STREQ(expected_str, actual_str); EXPECT_STREQ(expected_str, actual_str); 两个C字符串有相同的内容<br>ASSERT_STRNE(str1, str2);&nbsp;&nbsp; EXPECT_STRNE(str1, str2); 两个C字符串有不同的内容<br>ASSERT_STRCASEEQ(expected_str, actual_str); EXPECT_STRCASEEQ(expected_str, actual_str); 两个C字符串有相同的内容，忽略大小写<br>ASSERT_STRCASENE(str1, str2);&nbsp;&nbsp; EXPECT_STRCASENE(str1, str2);&nbsp;&nbsp; 两个C字符串有不同的内容，忽略大小写<br><br>ASSERT_*版本的断言失败时会产生致命失败，并结束当前函数。EXPECT_*版本的断言产生非致命失败，而不会中止当前函数。通常更推荐使用EXPECT_*断言，因为它们运行一个测试中可以有不止一个的错误被报告出来。但如果在编写断言如果失败，就没有必要继续往下执行的测试时，你应该使用ASSERT_*断言。 </p>
<p>&nbsp;因为失败的ASSERT_*断言会立刻从当前的函数返回，可能会跳过其后的一些的清洁代码，这样也许会导致空间泄漏。根据泄漏本身的特质，这种情况也许值得修复，也可能不值得我们关心——所以，如果你得到断言错误的同时，还得到了一个堆检查的错误，记住上面我们所说的这一点。 </p>
<p>&nbsp;要提供一个自定义的错误消息，只需要使用&lt;&lt;操作符，或一个&lt;&lt;操作符的序列，将其输入到框架定义的宏中。下面是一个例子：<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">ASSERT_EQ(x.size(),&nbsp;y.size())&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Vectors&nbsp;x&nbsp;and&nbsp;y&nbsp;are&nbsp;of&nbsp;unequal&nbsp;length</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;&nbsp;&nbsp;&nbsp;<br><img id=Codehighlighter1_112_188_Open_Image style="DISPLAY: inline" onclick="this.style.display='none'; Codehighlighter1_112_188_Open_Text.style.display='none'; Codehighlighter1_112_188_Closed_Image.style.display='inline'; Codehighlighter1_112_188_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_112_188_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_112_188_Closed_Text.style.display='none'; Codehighlighter1_112_188_Open_Image.style.display='inline'; Codehighlighter1_112_188_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></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;x.size();&nbsp;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">i)&nbsp;</span><span id=Codehighlighter1_112_188_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_112_188_Open_Text style="DISPLAY: inline"><span style="COLOR: #000000">{&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;EXPECT_EQ(x[i],&nbsp;y[i])&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Vectors&nbsp;x&nbsp;and&nbsp;y&nbsp;differ&nbsp;at&nbsp;index&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;i;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">&nbsp;&nbsp;</span></div>
任何能够被输出到ostream中的信息都可以被输出到一个断言宏中——特别是C字符串和string对象。如果一个宽字符串（wchar_t*，windows上UNICODE模式TCHAR*或std::wstring）被输出到一个断言中，在打印时它会被转换成UTF-8编码。<br><br>如果需要将信息输出到XML中。在参数中使用：<br>--gtest_output=xml:test.xml<br>就可以了
<img src ="http://www.cppblog.com/Randy/aggbug/66961.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Randy/" target="_blank">Randy</a> 2008-11-14 22:54 <a href="http://www.cppblog.com/Randy/archive/2008/11/14/66961.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>