读书笔记
hanyu1980
这个作者很懒,什么都没留下…
展开
-
Exceptional C++ Style之8
第8条 友元模板 友元的声明有四种准则:一、如果给出显示的模板实参,将被认为是模板的具现。二、如果被一个名字空间或者类所限,在这个限定内确实可以匹配的函数或者类,那么就匹配这个东东。三、如果这之内有一个可以匹配的函数模板,那么可以认为是这个函数模板的隐式特化。四、否则就是一个普通函数。这里面给出的准则是关于友元的声明,可以写成如下两种:friend void boost::原创 2006-03-07 13:17:00 · 694 阅读 · 0 评论 -
Exceptional C++ Style之10
第10条 导出限制之二:相互影响、可用性问题以及准则 export对C++来并不是如一个普通的关键字那么简单,它可能会导致一些规则的颠覆。而先前合法的一些使用会因为export的出现而产生二义性。更加复杂的是编译和链接不再像以往那么容易区别。Linker甚至会回头重新进行编译。这可在以前从来没有过。 对于大多数人来,export没有意义,比如我,手头上没有支持exp原创 2006-03-09 10:47:00 · 611 阅读 · 0 评论 -
Exceptional C++ Style之11
第11条 try和catch 写在异常安全之前,是我看了一部分代码,看了很多的try/catch all的咚咚,I suppose是不是这些Catch都是异常安全的。事实上,我认为很多catch all仅仅为了保证程序还能运行,因为除了一行日志之外,我看不到什么别的咚咚。我不认为所有的地方都不需要做额外的动作。 异常代码不是越多越多,事实上,异常代码影响C++的效率原创 2006-03-09 13:59:00 · 645 阅读 · 0 评论 -
Exceptional C++ Style之12
第12条 异常安全性:值得吗 资源获取即初始化,这里用到了智能指针的概念也就是说把资源管理的工作交给了构造函数和析构函数,这应该是个比较流行的办法,我遇到过因为分支产生的内存泄漏问题。 如果可以的话,不要贸然返回。但是有什么好的办法?我在我的实践中考虑到效率的问题,需要及早返回。记得在Stack中讨论Top()和Pop(),这就是为什么函数要功能单一的真谛,如果需要原创 2006-03-09 14:31:00 · 701 阅读 · 0 评论 -
Exceptional C++ Style之16
第16条 (几乎)私有 顺序,顺序。这里说的是重载三部曲——名字查找,重载决议,可访问性检查。这里写这个是因为重载决议在可访问性检查之前。所以出现可访问性问题,编译器不会因为隐式转换而通过重载避开,这里就是一个编译错误。Public和private是控制可访问性,而不是可见性,这点很重要。对于一个私有变量来说,似乎是无法保护的,C++中 存在强大的指针,可以在知道内存布局的情况原创 2006-03-09 16:34:00 · 769 阅读 · 0 评论 -
Exceptional C++ Style之17
第17条 封装 封装的准则是将所有的数据成员放在私有区段。唯一的例外是C风格的struct,后者的意图并不在封装什么,因而其所有成员都可以是公用的。 接口是最需要在第一时间就做对的事情,其他东西都可以在后期进行修正。如果一开始接口就错了,那么以后可能很难有机会修正。 这个原则似乎不是那么明显,但如果在实际工程中,你就会发现这点有多么的重要。原创 2006-03-10 11:06:00 · 743 阅读 · 0 评论 -
Exceptional C++ Style之18
第18条 虚拟 虚拟也许是C++区别C的一个最显著特征之一。和模板不同,虚拟是需要带来运行期消耗的,具体原理参见《Inside C++ Object Model》。但是付出的代价表明,这个特性是绝对值得付出的。 我们的设计通常是这样的,在一个基类中定义一些接口,这些接口都是虚拟的。期待派生类来进行实现,但是这个地方Sutter给出一个原则,在这个基础上更进一步。Su原创 2006-03-10 11:56:00 · 746 阅读 · 0 评论 -
Exceptional C++ Style之13
第13条 对异常规格的实际考虑 令人遗憾的是,我没有在实际代码中看见一行异常规格。typedef不支持异常规范。对虚函数来数,派生类对异常规范比基类更加严格。 异常规格常常是个善意的谎言,说这句话的时候,我其实有点疑惑,真的是善意?有时候可能叫做玩忽职守,或者什么其他的,但是这个地方真的是个问题。我完全认为这可能成为一个空头的承诺。 事实上,不要为函数加上原创 2006-03-09 15:08:00 · 703 阅读 · 0 评论 -
Exceptional C++ Style之14
第14条 顺序、顺序! 继承是除了友元外,最强的联系,继承不是解决一切问题的办法,所以不要遇到什么事情就继承。还有关于顺序的问题,请参见《Inside C++ Object Model》,那里面远比这说的详细。原创 2006-03-09 15:17:00 · 659 阅读 · 0 评论 -
Exceptional C++ Style之15
第15条 访问权限的使用 这似乎是对C++语言的一些讨论,但我想,在外部修改对象可以么?进程间。 我想语音级别上是很严密的,剩下的就是系统级安全问题了。原创 2006-03-09 15:45:00 · 686 阅读 · 0 评论 -
重构之简化函数调用
1.Rename Method(重新命名函数)修改函数名称。2.Add Parameter(添加参数)为函数添加一个对象参数,让该对象带进函数所需信息。3.Remove Parameter(移除参数)将参数去除。4.Separate Query from Modifier(将查询函数和修改函数分离)建立两个不同的函数,其中一个负责查询,另一个负责修改。5.Param原创 2006-02-08 18:26:00 · 833 阅读 · 0 评论 -
重构之在对象之间搬移特性
1.Move Method(搬移函数)你的程序中,有个函数与其所驻class之外的另一个class进行更多交流:调用后者,或者被后者调用。2.Move Field(搬移值域)在target class建立一个new field,修改source field的所有用户,令它们改用new field。3.Extract Class(提炼类)建立一个新Class,将相关的值域和函数从原创 2006-02-08 18:30:00 · 790 阅读 · 0 评论 -
重构之大型重构
1.Tease Apart Inheritance(梳理并分解继承体系)建立两个继承体系,并通过委托关系(delegation)让其中一个可以调用另一个。2.Convert Procedural Design to Objects(将过程化设计转化为对象设计)将数据记录(data records)变成对象,将行为分开,并将行为移入相关对象之中。3.Separate Domain f原创 2006-02-08 18:24:00 · 856 阅读 · 0 评论 -
重构之重新组织数据
1.Self Encapsulate Field(自封装值域)为这个值域建立取值/设值函数(getting/setting methods),并且只以这些函数来访问值域。2.Replace Data Value with Object(以对象取代数据值)将数据项变成一个对象。3.Change Value to Reference(将实值对象改为引用对象)将Value Objec原创 2006-02-08 18:29:00 · 784 阅读 · 0 评论 -
重构之重新组织函数
1.Extract Method将这段代码放进一个独立的函数里,让函数名称解释该函数的用途。用来搞定Long Method2.Inline Method在函数调用点插入函数体本体,然后移除该函数。3.Inline Temp将所有对该变量的引用动作,替换成对它赋值的那个表达式自身。确定该赋值只用一次。4.Replace Temp With Query将这个表达式提原创 2006-02-08 18:31:00 · 703 阅读 · 0 评论 -
重构之简化条件表达式
1.Decompose Conditional(分解条件式)从if、then、else三个段落中分别提炼出独立函数。2.Consolidate Conditional Expression(合并条件式)将这些测试合并为一个条件式,并将这个条件式提炼成为一个独立函数。3.Consolidate Duplicate Conditional Fragments(合并重复的条件片断)将原创 2006-02-08 18:27:00 · 857 阅读 · 0 评论 -
重构之Bad Smells
1.Duplicated Code(重负的代码)2.Long Method(过长的代码)3.Large Class(过大类)4.Long Parameter List(过长参数列)5.Divergent Change(发散式变化)6.ShotgunSurgery(散弹式修改)7.Feature Envy(依恋情结)8.Data Clumps(数据泥团)9.Primi原创 2006-02-08 18:20:00 · 884 阅读 · 0 评论 -
重构之处理概括关系
1.Pull Up Field(值域上移)将此一值域移至Superclass。2.Pull Up Method(函数上移)将该函数移至superclass。3.Pull Up Constructor Body(构造函数本体上移)在superclass中新建一个构造函数,并在subclass构造函数中调用它。4.Push Down Method(函数下移)将这个函数移到相原创 2006-02-08 18:21:00 · 857 阅读 · 0 评论 -
C++编程思想之操作符=重载
以前的认识存在一个误区,如下:Type a = b;//这个表示调用拷贝构造函数,而没有调用操作符=而 a = b;//只调用了操作符=我以前的认识存在误区,所以在实现深拷贝的时候,就需要不仅重载拷贝构造函数,而且要重载操作符=。我以前没有理解这个问题,认识有点片面,个人认为拷贝构造函数都是递归的,在没有的情况下,才使用位拷贝。拷贝构造函数和默认构造函数都是递归原创 2006-02-13 10:01:00 · 1087 阅读 · 0 评论 -
深度探索C++对象模型之局部静态对象
在读这本书的时候,涉及到这个问题,局部静态对象是个比较有意思的东西,我记得《Modern C++ Design》中就提及过这个东西,在Singleton中使用了这个巧妙的方式。 先说一下局部对象的性质,在第一次执行到的时候初始化,而在最后的时候析构,也就是说如果它生成后,在程序的运行期,它都是有效的,存在于静态存储区,尽管它往往不是时时可见,但可以经由指针操作它,因为原创 2006-02-15 10:46:00 · 830 阅读 · 0 评论 -
C++编程思想之默认拷贝构造函数
C++中类调用拷贝构造函数生成一个对象的情况下,如果拷贝构造函数不存在,则会自动生成一个默认拷贝构造函数。默认构造函数会递归调用成员的拷贝构造函数。如果成员不存在拷贝构造函数,它会按位拷贝。原创 2006-02-13 09:31:00 · 1391 阅读 · 0 评论 -
C++编程思想之SmartPoint
SmartPoint是C++发展的一个热点。我相信Java此类的语言还是存在着他们的优点,这是SmartPoint出现的一个根源,指针是个好东东,但并非放之四海皆准的好东西。指针功能强大,功能强大的另一个意思就是如果出错,也将是灾难性的后果。Java之所以受欢迎是因为它的屏蔽指针也垃圾收集机制。对C++来说,实现这一点并非什么非常困难的事情,现在智能指针正在朝着这个方向努力。我们可以很容易的把指针原创 2006-02-13 09:36:00 · 2510 阅读 · 0 评论 -
C++编程思想(第2卷)之深入探索string
以前string用的很少,一般使用char array或者CString,之所以不使用,是因为还不了解string的机制,不会用而并非因为string不好用。本文结合string的源码,深入探索string的用法。 那么从构造开始:basic_string(const E *s, const A& al = A());//字符串 basic_string(c原创 2006-02-13 11:37:00 · 967 阅读 · 0 评论 -
C++编程思想之指向成员的指针
C++存在指向类成员的指针,可以在调用的时候定义:int Object::*ptr = &Object::I;Object类中存在一个成员:int i,指针就是指向这个成员的。类中是没有地址的,所以调用不可以用类来调用,需要使用对象来调用(非静态情况)。Object o;Object* oPtr;调用就可以:o.*ptr;oPtr->*ptr;目前来看没有看到有什么原创 2006-02-13 09:33:00 · 759 阅读 · 0 评论 -
C++编程思想(第2卷)之异常
之前,写过两篇关于异常的Blog,不过仅仅涉及到异常比较浅的层面,现在我开始阅读《C++编程思想》关于异常的章节,希望进入到异常比较深的层面中去。 在C中,使用了一些比较传统的错误处理机制。通常这样的方法有三种:1. 使用返回值或者全局标志,C中提供了errno和perror()这样的函数。这种函数我没有使用过,但是我用过windows的出错机制。在w原创 2006-02-13 10:08:00 · 1512 阅读 · 0 评论 -
C++编程思想(第2卷)之查找内存泄漏
之所以单独写这一章是因为发现了两个非常好用的保留字__FILE__和__LINE__。而C++编程思想把这两个关键字用在查找内存泄漏上,我觉得非常管用。 从用的手段上来说,是用自定义的宏代替关键字。这并称为Dark Technique。但是不管黑猫白猫,能抓住老鼠的就是好猫。用了C++编程思想用用于测试的代码内存泄漏的代码,觉得非常好用。但是还有一定的遗憾。这仅仅适用原创 2006-02-13 10:09:00 · 1117 阅读 · 0 评论 -
Exceptional C++ Style之21
第21条 内存中的容器之二:它到底有多大 这篇写的是各种容器类的空间消耗,其实这并不是我所关注的问题。在目前的硬件条件下,通常对效率的要求往往超过了对空间的要求,我想选择一个数据结构的基本要求就是具有足够的特性,尤其是效率。 需要特别注意的是一个地方就是数据的对齐,对于整个系统来说,进程内部的数据是不存在这样的问题(用指针移位来进行计算的除外)。通常来说,进程间的数原创 2006-03-29 21:18:00 · 644 阅读 · 0 评论 -
Exceptional C++ Style之20
第20条 内存中的容器之一:内存管理的层次 内存分配的层次通常是分这么几层,从内到外分别为,操作系统内核,operator new和malloc,标准容器和分配器,用户定义的容器和分配器。 在代码编写的时候,需要注意各层做了什么,明白各层的策略和职责是非常必要的。原创 2006-03-29 21:11:00 · 560 阅读 · 0 评论 -
Exceptional C++ Style之22
第22条 进行new的操作,也许会抛出异常之一:new的方方面面 事情总是自以为了解很多,但实际上总有呼略的侧面,对new的理解也是如此。这一条对new做了很好的总结。通常的new,不抛出异常的new,定位的new。 在全局范围内,可以对前两种new进行重载,但是在类范围内,可以对所有类型的new进行重载。 关于名字隐藏,编译器对函数和对象的查找是从原创 2006-03-29 21:57:00 · 677 阅读 · 0 评论 -
Exceptional C++ Style之23
第23条 进行new的操作,也许会抛出异常之二:内存管理中的实际问题 我从来没有尝试过nothrow new,因为这个地方并不是问题的关键,用普通new我没有遇到过问题,而且问题是如果普通new都出现问题的时候,其他什么伎俩都没有什么意思了。问题还有就是什么时候nothrow new会返回NULL?这太罕见了,甚至如果我不偏执的话,也许一辈子也遇不到。通信包的应用可以导致Buffe原创 2006-03-30 18:22:00 · 727 阅读 · 0 评论 -
Exceptional C++ Style之3
第3条 字符串格式化的“动物庄园”之二:标准的(极度优雅的)替代方案方案一、snprintf 这看上去是最简单的替代方案,给出的这个长度,可以有效限制buf的溢出。长度输入错误?出现这种事情自己检讨。比较来说,永远不要用sprintf,这好像有点残酷,不过snprintf其实是一回事。类似的情况还有很多,在这里就不赘述了。 方案二、std::stringstream原创 2006-03-01 13:16:00 · 707 阅读 · 0 评论 -
Exceptional C++ Style之4
第4条 标准库成员函数 关于mem_fun和mem_fun_ref的问题,先前在《Effective C++》中就写过了。这里不多些了。使用mem_fun,但不要用在标准库上。看了半天终于看懂了这段的意思,这个意思是在标准库中充斥着peekaboo参数,也就是说,你不一定能绑定正确的函数。所以,原则是,绑定你能控制的函数,对于标准库,这不是个人可以控制的,即使不同的实现也会有很原创 2006-03-01 16:53:00 · 691 阅读 · 0 评论 -
Exceptional C++ Style之6
第6条 泛型性的风味之二:够“泛”了吗 对泛型编程来说,如果需要限定模板输入参数是指针,那么它不算是一个泛型,只能说是一个特化版本。因为准则是,指针是迭代器,迭代器并非总是指针。当用一个模板来实现另一个模板,特别是它们存在一定的关系,那么这种关系有可能形成一些限制,导致某些泛型性的丧失。 如果拥有标准模板库中,更好的实现函数,不妨用模板库中的函数,作为特化版本,可以原创 2006-03-03 11:22:00 · 590 阅读 · 0 评论 -
Exceptional C++ Style之7
第7条 为什么不特化函数模板 有一个概念,我以前对偏特化不是特别清晰明了,模板分成类模板和函数模板,我原来是一致看待的。但是事实上,函数模板能不能偏特化,只能重载,每个看个偏特化的函数模板其实都是重载。 函数模板并不参加重载决议,只有当主模板被选中,才有可能去选择某个特化版本。而且在选择主模板的时候,编译器并不关心特化模板。所以,如果你确实需要某个特化版本,那么写成原创 2006-03-07 10:52:00 · 645 阅读 · 0 评论 -
Exceptional C++ Style之2
第2条 字符串格式化的“动物庄园”之一:sprintf 对于Sutter来说,他肯定很不喜欢sprintf。我也不是特别的喜欢,但是不要忘了他的优点,简单,效率高,对我来说,效率非常非常重要,以至于它要成为一个习惯。 我们来表述一下sprintf的原罪,类型安全性,这不单单是sprintf吧,所有格式化的c函数都存在这个问题,我们可以把它认为是c的原罪。那么,nex原创 2006-03-01 11:45:00 · 679 阅读 · 0 评论 -
Exceptional C++ Style之24
第24条 常量优化 Const的主要作用在代码安全性上,如果是性能优化的话,不妨用const引用。Const直接使用很少能直接改善性能,例外就是对象本身存在对const的优化。原创 2006-03-30 18:35:00 · 723 阅读 · 0 评论 -
Exceptional C++ Style之25
第25条 再论内联 我个人的习惯是写一大堆private的内联函数,难道这也有错么?但是编译器并不是那样的听话,写了inline就内联,不写就不内联。Inline关键字可能对于很多编译器来说,means建议。跨模块内联,这可是新技术,但是已经有编译器支持这一特性,这就需要连接期做一点工作了。安装时,很新颖,但是可能CLR、JVM真的支持这一特性,对于VC6这可能就不是这样了。运行期原创 2006-03-30 19:00:00 · 845 阅读 · 0 评论 -
Exceptional C++ Style之19
第19条 对派生类施加规则 不要在析构函数中抛出异常,这是在《C++编程思想》中写的很明白的事情。不要使用异常规格,这在以前也看过,当然,目前没有足够的好处促使编写异常规格。 避免编写虚的操作符重载,具体原因我也没有看见。 需要对派生类加上限制的话,可以考虑在基类将其访问权限改为不可访问。尽量用编译期错误代替运行期错误。原创 2006-03-29 21:06:00 · 663 阅读 · 0 评论 -
Exceptional C++ Style之26
第26条 数据格式和效率之一:什么时候压缩是真正重要的 对于标准容器来说的话,没有谁是最好的。通常需要根据实际的情况来选择最合适的容器。原创 2006-04-03 16:16:00 · 653 阅读 · 0 评论 -
Exceptional C++ Style之5
第5条 泛型性的风味之一:基础 这 部分其实新的内容不多,提出的主要概念是两个,第一个是编译期多态的概念。我对这部分的理解是,编译期多态和运行期多态,并不是说可以随意替换。它们只存 在部分交集。编译期多态的好处在于消耗花在编译期,而运行期的额外消耗为零。如果条件允许应该适当用编译期多态来替代运行期多态。 至于模板具现的二义性问题,在《C++编程思想》的第二卷中,已经原创 2006-03-02 13:38:00 · 654 阅读 · 0 评论