﻿<?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++博客-lucky420-文章分类-读书笔记</title><link>http://www.cppblog.com/lucky420/category/1767.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 19 May 2008 12:20:45 GMT</lastBuildDate><pubDate>Mon, 19 May 2008 12:20:45 GMT</pubDate><ttl>60</ttl><item><title>读《C＋＋编程规范》</title><link>http://www.cppblog.com/lucky420/articles/7154.html</link><dc:creator>随便写写</dc:creator><author>随便写写</author><pubDate>Mon, 15 May 2006 01:52:00 GMT</pubDate><guid>http://www.cppblog.com/lucky420/articles/7154.html</guid><wfw:comment>http://www.cppblog.com/lucky420/comments/7154.html</wfw:comment><comments>http://www.cppblog.com/lucky420/articles/7154.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lucky420/comments/commentRss/7154.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lucky420/services/trackbacks/7154.html</trackback:ping><description><![CDATA[
		<span style="COLOR: red">组织和策略问题</span>
		<br />＃0 了解哪些东西不应该标准化<br />注释不是越多越好，应该注意实用原则，主要用来解释方法和原理<br /><br />＃1 在高警告级别下编译，理解并排除所有的警告<br />如果引用的第三方库有警告，可以用自定义的头文件包含这个库的头文件，在自定义头文件中忽略这些警告。<br />如： 
<div class="code">#pragma warning(push)//保存当前的警告<br />#pragma warning(disable:4512)<br />#pragma warning(disable:4180)<br />#include &lt;boost/lambda/lambda.hpp&gt;//第三方头文件<br />#pragma warning(pop)//恢复到之前的警告</div><p><br />＃2 使用自动构建系统<br />使用单操作的自动化构建<br /><br />＃3 使用版本控制系统<br />CVS。不要让文件长时间登出，确保登入的代码不会影响构建成功<br /><br />＃4 在代码审查上投入<br />更多的关注有助于提高质量。亮出自己的代码，阅读别人的代码。<br /><br /><span style="COLOR: red">设计风格</span><br />不成熟的优化是程序涉及中的万恶之源<br />＃5 一个实体应该只有一个紧凑的职责<br />一次只解决一个问题<br /><br />＃6 正确、简单和清晰第一<br />简单就是美（Keep It Simple Software，KISS）。<br />使用最简单的有效技术。<br /><br />＃7 编程中应该知道何时和如何考虑可伸缩性<br />集中精力改善算法的O(N)复杂性，而不是进行小型的优化。<br />要时刻了解算法的实际复杂性<br /><br />＃8 不要进行不成熟的优化<br />决不要过早进行优化，再三测试，然后在必要的时候进行优化<br />让一个正确的程序更快，比让一个快速的程序正确，要容易的多。<br />优化之前应进行度量，度量之前必须确定优化的目标。<br /><br />＃9不要进行不成熟的劣化<br />放松自己，轻松编程<br />引用传递代替值传递<br />使用前缀++代替后缀++.<br />使用初始化列表代替构造函数中赋值<br />使用抽象和库<br /><br />＃10 尽量减少全局和共享数据<br />共享容易导致冲突，增加耦合度<br />用通信方式代替数据共享<br />尽量降低类间的耦合，减少交互<br /><br />＃11 隐藏信息<br />不要从任何提供抽象的实体中公开数据<br /><br />＃12 懂得何时和如何进行并发性编程 （* 我没多少经验，难以理解）<br />避免死锁，活锁和恶性竞争条件<br /><br />＃13 确保资源为对象所拥有，使用显式的RAII和智能指针<br />资源获取即初始化（RAII）<br />分配资源后立即赋给属主对象。<br />永远不要在一条语句中分配一个以上的资源<br />当需要配对的获取/释放函数调用时，都应该将资源封装在一个对象中。注意复制构造和赋值操作，以及自身赋值 </p><p> </p><p><span style="COLOR: red">编程风格 </span><br />＃14 宁要编译时和连接时错误，也不要运行时错误<br />能在编译时做的事就不要推迟到运行时。<br /><br />＃15 积极使用const<br />当知道某个值不会改变时就把它设为const。把const变成定义值时的默认选项<br />使用mutable<br /><br />＃16 避免使用宏<br />只在几个无法避免的地方使用：<br />#include 保护符<br />#ifdef和#if defined<br />assert实现<br /><br />＃17 避免使用魔数<br />使用符号名称代替它，符号名称易于理解和维护<br />使用const,枚举类型活函数<br /><br />＃18 尽可能局部地声明变量<br />变量的作用域越小越好，生存期越短越好<br /><br />＃19 总是初始化变量<br />初始化数组和结构的简单方法： </p><div class="code">ing total[100] = {0};<br />struct Data<br />{<br />int i;<br />double d;<br />char szName[10];<br />};<br />Data d={0};</div><p>注意，volatile型数据不需要程序对其进行初始化<br /><br />＃20 避免函数过长，避免嵌套过深<br /><br />＃21 避免跨编译单元的初始化依赖<br />保持初始化顺序<br />尽量避免名称空间级的变量<br /><br />＃22 尽量减少定义性依赖。避免循环依赖<br />如果可以用前向声明就不要#include<br />只有两种情况需要某个类的完整定义：<br />1 需要知道该类的大小<br />2 需要命名或者调用该类的成员<br />打破循环的一个方法就是，不要让高层模块依赖低层模块，而是让两者都依赖于抽象<br /><br />＃23 头文件应该自给自足 （* 一值对什么时候应该包含头文件很迷惑，好好理解一下＃22和＃23）<br />应该确保所编写的每个头文件都能够独自编译，即当需要用到某个头文件中的内容时，只需要包含此文件，而不需要包含其他的文件。<br />模板是在其定义处编译的，但非独立名称或者类型要等到模板实例化时才编译。<br /><br />＃24总是编写内部＃include保护符，决不要编写外部＃include保护符 </p><div class="code">//for foo.h<br />#ifndef FOO_H_INCLUDED_<br />#define FOO_H_INCLUDED_<br />//......<br />#endif<br /><br /><span style="COLOR: red">函数与操作符 </span><br />＃25 正确地选择通过值，（智能）指针或引用传递参数<br /><br />＃26 保持重载操作符的自然语义<br /><br />＃27 优先使用算术操作符和赋值操作符的标准形式<br />定义了a+b 也应该定义a+=b.并且用用+=来定义+.<br /><br />＃28 优先使用++和－－的标准形式。优先调用前缀形式<br />应该用前缀形式实现后缀形式<br />T&amp; T::operator++() //前缀形式<br />{<br />//执行递增<br />return *this;<br />}<br /><br />T T::operator++(int) //后缀形式<br />{<br />T old(*this); //保存旧值<br />++*this; <br />return old;<br />}<br /><br />＃29 考虑重载以避免隐含类型转换<br />奥卡姆剃刀原理：如无必要勿增对象。重载会引起临时对象的创建。<br /><br />＃30 避免重载&amp;&amp; ||和，<br />因为内置版本的特殊之处在于：从左到右求值，（对&amp;&amp; ||）短路求值<br />而函数参数总是会对所有参数进行求值，且求值顺序是不确定的。<br /><br />＃31 不要编写依赖于函数参数求值顺序的代码<br />函数参数的求值顺序是不确定的<br /><br /><span style="COLOR: red">类的设计与继承</span><br />软件开发最重要的一个方面就是弄清楚自己要构建的是什么。<br />＃32 弄清所要编写的是哪种类<br />值类 模仿内置类型<br />基类 构成类层次结构<br />traits类<br />策略类<br />异常类<br />附属类<br /><br />＃33 用小类代替巨类<br />分而治之：小类易于编写、测试和使用<br /><br />＃34 用组合代替继承<br />继承是仅次于友元的第二紧密的耦合关系<br />软件工程中的一条明智原则就是，尽量减少耦合<br />通过（智能）指针保存对象，可以减少头文件依赖性<br />Pimpl技术：将所有私有成员聚合在一个不透明的指针后面<br />必须使用继承的情况：<br />1 需要改写虚拟函数<br />2 需要访问保护成员<br />3 需要在基类前构造已使用过的对象，或者在基类之后销毁此对象（基类比子类先构造，后析构）<br />4 需要操心虚拟基类<br /><br />＃35 避免从非必要设计成基类的类中继承<br />独立类和基类的设计有不同的考虑<br /><br />＃36 优先提供抽象接口<br />优先采用实现了抽象接口的设计层次结构<br /><br />＃37 公用继承即可替换性。继承，不是为了重用，而是为了被重用<br />公用继承描述的是“is-a”或者“works like a”关系<br />组合描述的是“用...来实现”关系<br /><br />＃38 实施安全的改写<br /><br />＃39 考虑将虚拟函数声明为非公用的，将公用函数声明为非虚拟的<br /><br />＃40 避免提供隐式转换<br />隐式转换构造函数：能够用一个参数调用且未声明为explicit的构造函数。<br /><br />＃41 将数据成员设为私有的、无行为的聚集<br /><br />＃42 不要公开内部数据<br /><br />＃43 明智地使用Pimpl<br />实现编译器防火墙<br />class A<br />{<br />private:<br />struct Impl;//存储所有私有成员<br />shared_ptr&lt;Impl&gt; pimpl_;<br />}<br /><br />＃44 优先编写非成员非友元函数<br /><br />＃45 总是一起提供new和delete<br /><br />＃46 如果提供类专门的new，应该提供所有标准形式（普通、就地和不抛出）<br />void* operator new(std::size_t);//普通<br />void* operator new(std::size_t,std::nothrow_t) throw();//不抛出<br />void* operator new(std::size_t,void*);<br />定义了一个某种形式的重载会隐藏其他的重载形式 <br /><br /><span style="COLOR: red">构造、析构与复制</span><br />＃47 以同样的顺序定义和初始化成员变量<br />成员变量初始化顺序与在类中声明的顺序一致<br /><br />＃48 在构造函数中用初始化代替赋值<br /><br />＃49 避免在构造函数和析构函数中调用虚拟函数<br />虚拟函数在构造函数和析构函数中并不虚拟<br /><br />＃50 将基类析构函数设为公用且虚拟的，或者保护且非虚拟的<br /><br />＃51 析构函数、释放和交换绝对不能失败<br /><br />＃52 一致地进行复制和销毁<br />同时定义复制构造函数，复制赋值操作符和析构函数<br /><br />＃53 显式地启用或禁止复制<br /><br />＃54 避免切片，在基类中考虑用克隆代替复制<br /><br />＃55 使用赋值的标准形式<br /><br />＃56 只要可行，就提供不会失败的swap<br /><br /><span style="COLOR: red">名字空间与模块</span><br />模块：同一个人或小组维护的紧凑的发布单元<br />＃57 将类型及其非成员函数接口置于同一名字空间中<br />对于一个类X而言，所有在同一个名字空间中提及X和随X一起提供的函数逻辑上都是X的一部分，它们形成了X接口的组成部分。<br />ADL 参数依赖查找<br /><br />＃58 应该将类型和函数分别置于不同的名字空间中，除非有意想让它们一起工作<br /><br />＃59 不要在头文件中或者＃include之前编写名字空间using<br />在头文件中不要使用using指令或声明，而应该显示使用名字空间限定所有名字<br />不要在＃include之前使用using<br /><br />＃60 避免在不同的模块中分配和释放内存<br /><br />＃61 不要在头文件中定义具有链接的实体<br /><br />＃62 不要允许异常跨越模块边界传播<br /><br />＃63 在模块的接口中使用具有良好可移至性的类型<br />不要让类型出现在波快的外部接口中，除非能确保所有的客户代码都能够正确地理解该类型。<br />使用客户代码能够理解的最高层抽象。<br />抽象层越低，可移至性越好。<br /><br /><span style="COLOR: red">模板与泛型</span><br />＃64 理智地结合静态多态性和动态多态性<br />静态多态性是指模板类和模块函数<br />动态多态性是指类的虚拟函数和间接引用<br /><br />＃65 有意地进行显示自定义<br /><br />＃66 不要特化函数模板<br /><br />＃67 不要无意地编写不通用的代码 <br /><br /><span style="COLOR: red">错误处理与异常 </span><br />问题不在与我们是否会犯错误，而在于我们是否会安排编译器和工具寻找错误。<br /><br />＃68 广泛地使用断言记录内部假设和不变式<br />一个事件中所含的信息量与该事件发生的概率是成反比的。<br />不要使用断言报告运行时错误<br /><br />＃69 建立合理的错误处理策略，并严格遵守<br />只在模块边界处改变错误处理机制<br /><br />＃70 区别错误与非错误<br />前条件<br />后条件<br />不变式<br /><br />＃71 设计和编写错误安全代码<br />基本保证：确保出现错误时程序会处于有效状态。<br />强保证：保证最终状态要么时最初状态，要么是所希望的目标状态。<br />不会失败保证：保证操作永远不会失败。<br /><br />＃72 优先使用异常报告错误<br />使用异常而不是错误码<br /><br />＃73 通过值抛出，通过引用捕获<br /><br />＃74 正确地报告、处理和转换错误<br /><br />＃75 避免使用异常规范<br /><br /><span style="COLOR: red">STL容器 </span><br />＃76 默认使用vector，否则，选择其他合适的容器<br /><br />＃77 用vector和string代替数组<br /><br />＃78 使用vector与非C++API交换数据<br />&amp;*iter:获取迭代器引用元素的地址<br /><br />＃79 在容器中只存储值和智能指针<br />在容器中存储值对象<br /><br />＃80 用push_back代替其他扩展序列的方式<br />push_back 是按指数级扩大容量的<br /><br />＃81 多用范围操作，少用单元素操作<br /><br />＃82 使用公认的惯用法真正地压缩容量，真正地删除元素<br />swap：<br />container&lt;T&gt;(c).swap(c);//去除多余容量的shrink-to-fit惯用法<br />container&lt;T&gt;().swap(c);//去除全部内容和容量的惯用法<br />c.erase(remove(c.begin(),c.end(),value),c.end());//删除元素的惯用法<br /><br /><span style="COLOR: red">STL算法 </span><br />多用算法，少用循环<br />＃83 使用带检查的STL实现<br /><br />＃84 用算法调用代替手工编写的循环<br />采取“处理此范围”的算法性思维方式，取代“处理每个元素”的循环式思路<br />使用boost.lambda库<br /><br />＃85 使用正确的STL查找算法<br />查找无序范围：find/find_if<br />查找有序范围：low_bound, upper_bound, equal_range, binary_search.<br />对有序范围，p=equal_range(first,last,value);distance(p.first,p.end);比count(first,last,value);更快<br /><br />＃86 使用正确的STL排序算法<br />开销从低到高：partition,stable_partition,nth_element, partial_sort(partial_sort_copy),sort,stable_sort<br /><br />＃87 使谓词成为纯函数<br />将谓词类型的operator()声明为const<br /><br />＃88 算法和比较器的参数应多用函数对象少用函数<br /><br />＃89 正确编写函数对象<br />将函数对象设计为复制成本很低的值类型。尽可能从unary_function或binary_function继承<br /><br /><span style="COLOR: red">类型安全 </span><br />＃90 避免使用类型分支，多使用多态<br /><br />＃91 依赖类型，而非其表示方式<br /><br />＃92 避免使用reinterpret_cast<br /><br />＃93 避免对指针使用static_cast<br />使用dynamic_cast<br /><br />＃94 避免强制转换const<br /><br />＃95 不要使用C风格的强制转换<br /><br />＃96 不要对非POD进行memcpy或者memcmp操作<br /><br />＃97 不要使用联合重现解释表达方式<br /><br />＃98 不要使用可变长参数<br />boost.format库<br /><br />＃99 不要使用失效对象。不要使用不安全函数<br />不要使用不安全的C语言遗留函数<br /><br />＃100 不要多态地处理数组<br />基类对象的数组和子类对象的数组是完全不同的类型 </div><img src ="http://www.cppblog.com/lucky420/aggbug/7154.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lucky420/" target="_blank">随便写写</a> 2006-05-15 09:52 <a href="http://www.cppblog.com/lucky420/articles/7154.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>