自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(25)
  • 收藏
  • 关注

原创 《Effective C++》读书笔记之item48:认识template元编程

1.模板元编程可以将部分执行期的任务提前至编译期完成,从而可以更早发现错误,更加高效(编译时间会变长,但是执行期的效率会更高)。2.模板元编程是图灵完备的,可以执行分支语句和循环(通过递归实现)。如解决阶乘问题的代码:template //一般情况,递推关系式struct Factorial{ enum{value = n * Factorial::value};};temp

2012-08-30 20:18:40 1779

原创 《Effective C++》读书笔记之item47:请使用traits classes表现类型信息

1.使用traits技术可以在编译期间获取某些类型信息,它要求对内置类型和用户自定义类型表现得一样好。标准模板库是把traits信息放到模板中,其中针对迭代器的被命名为iterator_traits,它是一个结构体:templatestruct iterator_traits;它的工作原理是:针对每一个类型IterT,在结构体中声明某个typedef名为iterator_

2012-08-30 19:53:29 709

原创 《Effective C++》读书笔记之item46:需要类型转换时请为模板定义非成员函数

1.在类外定义的模板函数,在实参具现化时不进行隐式类型转换:可以在函数调用过程中进行这样的转换,但是在能够调用一个函数之前,编译器必须知道那个函数存在,而为了知道它,必须先为相关的函数模板具现化参数类型。这是template C++与面向对象的C++不同的地方。对条款24中的例子进行模板化:templateclass Rational{ public: Rational(con

2012-08-30 17:41:02 1143

原创 《Effective C++》读书笔记之item45:运用成员函数模板接受所有兼容类型

1.注意一个特殊的行为:如果以带有派生关系的基类B和派生类D两类型分别具现化某个模板类,产生出来的两个具现体并不带有派生关系。2.如果模板类中需要接受多个兼容类型,可以声明一个成员函数模板。这样的函数往往应该是一个复制构造函数模板(泛化复制构造函数)和一个复制赋值重载函数模板以支持模板对象间的转换。如用户自定义的一个智能指针:templateclass SmartPtr{ publ

2012-08-29 20:34:18 769

原创 《Effective C++》读书笔记之item44:将与参数无关的代码抽离templates

1.模板类生成多个类和多个函数,所以任何模板类代码都不该与某个造成膨胀的模板参数产生相依关系。例如一个正方矩阵具有一个矩阵求逆的成员函数invert():template //该模板类支持n*n矩阵,元素类型为T,std::size_t属于非类型参数class SquareMatrix{ public: void invert(); //矩阵求逆运算 ...};如

2012-08-29 19:58:59 579

原创 《Effective C++》读书笔记之item43:学习处理模板化基类内的名称

1.注意从“面向对象的C++”转向“模板C++”时继承可能遭遇问题:由于基类模板可能被特化,而该特化版本可能会改变成员,因此C++拒绝在模板化基类中寻找继承而来的名称。2.实例:假设将信息传送到不同的公司去,传送方式包括明文传送和密文传送,采用模板类的设计方法:templateclass MsgSender{ public: ... void sendClear(const

2012-08-26 21:08:04 1223

原创 《Effective C++》读书笔记之item42:了解typename的双重意义

1.当声明模板类型参数时,class和typename的意义相同。2.模板内出现的名称如果依赖于某个模板参数,称为从属名称(dependent names);如果从属名称在类中呈嵌套状,称为嵌套从属名称。嵌套从属名称有可能导致解析困难,如:templatevoid print2nd(const C& container){ C::const_iterator* x; //可能

2012-08-25 20:37:31 649

原创 《Effective C++》读书笔记之item41:了解隐式接口和编译期多态

1.C++模板机制是一部完整的图灵机:它可以被用来计算任何可计算的值。由此发展出模板元编程,创造出“在C++编译器内执行并于编译完成时停止执行”的程序。2.类和模板都支持接口和多态,不同的是对类而言,接口是显式的,以函数签名(声明)为中心,多态则是通过运行期绑定(虚函数机制);对模板而言,接口是隐式的,奠基于有效表达式,多态则是通过模板具现化和函数重载解析,发生于编译期。

2012-08-23 21:02:20 597

原创 《Effective C++》读书笔记之item40:明智而审慎地使用多重继承

1.多重继承的缺点:(1)从一个以上的基类继承相同名称,可能导致歧义,使用时应当使用域作用符限定具体是哪个基类的成员。注意:在这种歧义中,C++用来解析重载函数调用的规则在起作用——在看到是否有个函数可取用之前,首先确定这个函数对此调用来说是最佳匹配,找到最佳匹配函数后才检验其可取用性。(2)如个一个基类有多个派生类,而更深层次的派生类从这些派生类中派生出来,基类如何构成这更深层次的派生类

2012-08-23 20:06:25 622

原创 《Effective C++》读书笔记之item39:明智而审慎地使用private继承

1.private继承意味着“根据某物实现出”,只有实现部分被继承,接口部分应略去;它只在软件“实现”层面上有意义,在软件设计层面上没有意义。private继承而来的基类成员都会在派生类中成为private属性;如果类之间是private继承关系,编译器不会自动将一个派生类对象转换为基类对象。2.private继承和复合都是“根据某物实现出”,在设计时应尽量使用复合,少使用private继承。

2012-08-22 19:58:27 577

原创 《Effective C++》读书笔记之item38:通过复合塑模出has-a或“根据某物实现出”

1.public继承是“is-a“的关系,而复合有”has-a“或”根据某物实现出(is-implemented-in-terms-of)“的意思——当复合发生在应用域内的对象之间,表现出has-a关系;当它发生于实现域内则是表示“根据某物实现出”的关系。2.实例:set的构造。标准程序库中有set模板,它“每个元素都耗用三个指针”,是用平衡查找树实现而成,使它们在查找、插入、删除元素时保证拥

2012-08-22 18:47:30 498

原创 《Effective C++》读书笔记之item37:绝不重新定义继承而来的缺省参数值

1.绝不重新定义继承而来的缺省参数值,它有两层意思:(1)如果函数是非虚函数,你根本不应该重新定义它,因此也谈不上改变缺省参数值了。(2)如果函数是虚函数,由于缺省参数值是“静态绑定”,即使使用基类类型的指针或引用指向派生类函数,并且函数以派生类所定义的版本动作,其缺少参数值仍旧是基类所定义的!C++使用这种方式是为了“运行期效率”,在编译期确定参数比在运行期确定效率要高。2.如以下继

2012-08-20 11:51:14 668

原创 《Effective C++》读书笔记之item36:绝不重新定义继承而来的non-virtual函数

1.任何情况下都不应该重新定义一个继承而来的非虚函数。如果重新定义,会出现“静态绑定”,只有声明为虚函数才能实现“动态绑定”。2.条款7“为多态基类声明虚析构函数”是本条款要求的特例:派生类可能有更多的成员变量和相应操作,因而析构函数必须与基类不同,采用虚析构函数的方法可以使用“动态绑定”从而产生安全的析构行为;反之,如果声明为非虚析构函数,必须重新定义,这和本条款的要求相违背。

2012-08-20 11:17:27 511

原创 《Effective C++》读书笔记之item35:考虑virtual函数以外的其他选择

1.虚函数的替代方案有:(1)使用non-virtual interface(NVI)方法,它是Template Method设计模式的一种特殊形式。使客户通过仅有的非虚函数间接调用私有的虚函数,该公有的非虚函数称为私有虚函数的“外覆器”(wrapper)。公有的非虚函数可以在调用虚函数前后做一些其他工作(如互斥器的锁定与解锁,验证约束条件等)。(2)将虚函数替换为“函数指针成员变量”,它

2012-08-19 21:13:57 1288 3

原创 《Effective C++》读书笔记之item34:区分接口继承与实现继承

1.public继承可以分为函数接口继承和函数实现继承。对基类而言,成员函数的接口总是被继承。根据在基类中的声明及定义,分为三种类型:纯虚函数:使派生类只继承其接口。可以为纯虚函数提供定义,但是调用时必须以ClassName::functionName()的方式调用。非纯虚函数(普通虚函数):使派生类继承接口和缺省实现。非虚函数(普通函数):使派生类继承接口和一份强制性实现。它不应当在派生

2012-08-18 20:11:41 597

原创 《Effective C++》读书笔记之item33:避免遮掩继承而来的名称

1.C++中函数的局部作用域会遮掩更大作用域中的同名的变量和函数。在局部作用域中,名称查找顺序为:局部作用域-外围更高一级的作用域-更外围作用域-全局作用域。2.在继承体系下,派生类的作用域包含在基类作用域下,因而在派生类中的同名变量会遮掩基类的变量。如:class Base{private:int x;public:virtual void mf1()

2012-08-18 18:56:58 463

原创 《Effective C++》读书笔记之item32:确定你的public继承塑模出is-a关系

1.public继承意味着“is a”(是一种)关系:任何一个继承类对象也是一个基类对象;任何可以出现基类对象的地方也可以出现一个继承类对象(例如函数的实参);任何一个可以在基类对象上所做的操作,同样也可以在派生类上操作(结果可能是设计者想要的,也可能是不想要的):“可以”是指编译器不报错,但是如果它违反了设计者的意愿,应当采用“让编译器报错”的方式来显示错误,这比“运行时报错”要好。

2012-08-18 14:04:48 572

原创 《Effective C++》读书笔记之item31:将文件间的编译依存关系降至最低

1.如果一个源文件以头文件的形式包含了其他文件,则它们之间便形成了一种“编译依存关系”;一旦被包含的文件(或这些文件包含的其他文件)被修改,则每一个包含该源文件的其他文件都必须重新编译。以“前置声明”代替“头文件包含”似乎是一个好办法,但是会遇到一些问题:对诸如string这样的头文件而言,正确的前置声明比较复杂,因为会涉及模板(string是个typedef而非类)。事实上,前置

2012-08-18 12:22:34 1086

原创 《Effective C++》读书笔记之item30:透彻了解inlining的里里外外

1.内联函数使得对此函数的每一个调用都以函数本体替换,因而可以免除调用成本(保存寄存器并在返回时恢复,复制实参,转向新位置继续执行等)。但是同时,滥用内联函数可能会造成代码膨胀甚至导致内存不足。因此,调用频繁并且函数体较少的成员函数(或者友元函数)适合内联,而其他情况往往需要权衡得失。内联函数的声明:在类内定义(隐喻方式)或者显式地在函数前使用inline关键字。内联函数应该在头文件中定义

2012-08-17 21:06:44 571

原创 《Effective C++》读书笔记之item29:为“异常安全”而努力是值得的

1.“异常安全性”(exception safety)能够为函数带来两个好处:不泄漏任何资源;不允许数据败坏:操作未正确完成却已经改变了部分数据。以这样的思想设计的函数(异常安全性函数)提供以下三个保证,即具有三个安全性等级:基本承诺:如果抛出异常,程序内的任何事物仍然保持在有效状态下,没有任何对象或数据结构会因此而败坏,所有对象都处于一种内部前后一致的状态。但程序的现实状态不

2012-08-17 19:39:45 783

原创 《Effective C++》读书笔记之item28:避免返回handles指向对象内部成分

1.应当避免返回引用、指针或者迭代器指向对象内部。坏处有二:(1)破坏数据封装。对类来说,让仅有成员函数返回内部变量的地址(包括引用、指针或者迭代器)事实上破坏了数据封装。因此,条款20所说的“传引用比传值效率高”虽然正确,但是很多情况下为数据安全舍弃效率仍旧是值得的。对于需要保护的成员变量,当成员函数返回它们的地址时应当特别小心,这些函数不仅本身是const的(以操作const数据)

2012-08-16 20:29:22 432

原创 《Effective C++》读书笔记之item27:尽量少做转型动作

1.C++是强类型语言,一般编译器会检查出不适合的转型操作。2.类型转换的形式:旧式转型(两种方式本质相同):C风格:(T)expression。函数风格:T(expression)。新式风格(或C++风格):const_cast(expression):去除表达式的常量性,是C++中唯一能做此操作的转型操作符。dynamic_cast(expression):主要

2012-08-16 19:38:44 901

原创 《Effective C++》读书笔记之item26:尽可能延后变量定义式的出现时间

1.自定义变量(类)初始化时会调用构造函数,作用域结束后会调用析构函数,而当变量定义后却由于某种原因(异常或条件判断)而没有使用,便造成了资源浪费。因此,应当尽可能延后变量的定义,甚至应该延后直到给它初值实参为止,以防止无意义的“调用默认构造函数后再赋值”的过程。2.P115页有两个循环过程的比较://方法A:定义于循环外Widget w;for(int i = 0;i<n;+

2012-08-15 20:57:12 575

原创 《Effective C++》读书笔记之item25:考虑写出一个不抛异常的swap函数

1.STL中有swap()函数可以将两个对象的值相交换,定义类似于:namespace std{ template void swap(T&a, T& b){ T temp(a); a=b; b=temp; }}这个函数是异常安全性编程的核心,并且是用来处理自我赋值可能性的一个常见机制2.可以使用swap()函数的多个版本:默认的STL中的swap(

2012-08-15 20:31:52 611

转载 ScribeFire添加CSDN博客账户的方法出现问题:404

刚用上ScribeFire,能够添加新浪博客帐户并发表文章,但是添加CSDN账户问题出现问题。网上的方法已经很多了,基本上比较统一,转载一篇:http://blog.csdn.net/aqua_aqua/article/details/2033259但是我添加帐户总是失败:网上一搜这种情况还真不少见,大概近两年都是这种情况。不死心,给CSDN博客管理员发邮件询问,回复说:

2012-08-11 11:03:24 495

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除